-1

UserData = user_data, SecurityGroupIds=[sg.group_id] )

for bucket_name in sys.argv[1:]: try: response = s3.create_bucket(Bucket=ec2-assignbuke2, CreateBucketConfiguration={'LocationConstraint': 'eu-west-1'}) print (response) except Exception as error: print (error)

print(sg.group_id)

xRasp
  • 41
  • 1
  • 7
  • What is the problem with the code you have shown? – jarmod Mar 02 '21 at 14:37
  • Nothing, I need to access my instance through port 22 / 80 but I need to write boto3 code to handle my security group by creating a different security group each time and use this new id in the create instance method which is where I am stuck. – xRasp Mar 02 '21 at 14:41
  • Still not clear what your question is. If it's "how do I configure an ingress rule for an existing security group" then use [authorize_security_group_ingress](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.authorize_security_group_ingress). – jarmod Mar 02 '21 at 14:45
  • Ah yeah see I tried that a few hours ago but I kept getting this error message : "AttributeError: 'ec2.ServiceResource' object has no attribute 'authorize_security_group_ingress' " – xRasp Mar 02 '21 at 16:04
  • Ah, apologies, that method is part of the client API, not the resource API. If you have a SecurityGroup resource in hand then you can use [authorize_ingress](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.SecurityGroup.authorize_ingress). – jarmod Mar 02 '21 at 16:20
  • I'm a bit more confused when using this method compared to the client one, i'm trying to get port 80 and 22 accessible so will the FromPort and ToPort values be the same and do I have to fill in any of the 'string' values set? – xRasp Mar 02 '21 at 16:27
  • You can specify a range of consecutive port numbers (e.g. 8000-8200) or you can specify a single port (e.g. range 22-22). If you want ports 22 and 80, then you need two ingress rules (22-22 and 80-80). It might be valuable for you to use the AWS console to set up a security group with the two ingress rules you want and then use the awscli to describe that security group's ingress rules, so you can see how they should be set. – jarmod Mar 02 '21 at 16:36
  • I'm fine with making 2 ingress rules, only issue is that when I go to run them I get an error of "Traceback (most recent call last): File "newwebserver.py", line 14, in response = security_group.authorize_ingress( NameError: name 'security_group' is not defined " – xRasp Mar 02 '21 at 16:46
  • You named your variable `sg`, not `security_group`. – jarmod Mar 02 '21 at 16:50
  • Oh I did not know I could rename a method name to suit my variable perfectly fine. Now i'm getting an error of "botocore.exceptions.ClientError: An error occurred (InvalidGroup.NotFound) when calling the AuthorizeSecurityGroupIngress operation: The security group 'string' does not exist in default VPC 'vpc-f31a3095' " I'm wondering if I might need to input GroupName, Description, VPCId into the ingress or to put the security group ID of the default VPC in replacement of 'string' but there is no field called security_group in the ingress or is the error related to something else? – xRasp Mar 02 '21 at 17:05
  • That `sg` is not a method name. It's the name of a variable in your code, that you chose to name `sg`. I am going to guess, in the absence of your source code, that you have literally copied the text from the SDK documentation as `GroupName='string'`. You shouldn't do that. The documentation is telling you that the parameter name is `GroupName` and its value is of type string. In your case, it should be `GroupName='MyWebServer'`. – jarmod Mar 02 '21 at 17:14
  • Yeah that's what I asked if I needed to input values for 'string' but I guess that makes sense now, it's just what is to be inputted for values 'PrefixListIds' , 'GroupId', 'PeeringStatus', 'userId', 'VpcPeeringConnectionID' as I have everything else filled out I just cant find values for mentioned fields. – xRasp Mar 02 '21 at 17:34

1 Answers1

2

Here is an example of a boto3 script that creates a security group in a specific VPC, authorizes ingress from the internet on ports 22 and 80, and launches an EC2 instance into a public subnet of the given VPC.

import boto3

ec2 = boto3.resource("ec2", region_name="eu-west-1")

user_data = """#!/bin/bash
yum update -y
yum install httpd -y
systemctl enable httpd
systemctl start httpd"""

# TODO: configure these as needed
VPC_ID = 'vpc-1234'
SUBNET_ID = 'subnet-5678'
AMI_ID = 'ami-0fc970315c2d38f01'
KEYPAIR = 'AlexBpem'

sg = ec2.create_security_group(
    GroupName="MyWebServer", Description="WebServer", VpcId=VPC_ID
)

instance = ec2.create_instances(
    ImageId=AMI_ID,
    MinCount=1,
    MaxCount=1,
    InstanceType="t2.nano",
    KeyName=KEYPAIR,
    UserData=user_data,
    NetworkInterfaces=[
        {
            "SubnetId": SUBNET_ID,
            "DeviceIndex": 0,
            "AssociatePublicIpAddress": True,
            "Groups": [sg.group_id],
        }
    ],
)

response = sg.authorize_ingress(
    IpPermissions=[
        {
            "FromPort": 22,
            "ToPort": 22,
            "IpProtocol": "tcp",
            "IpRanges": [
                {"CidrIp": "0.0.0.0/0", "Description": "internet"},
            ],
        },
        {
            "FromPort": 80,
            "ToPort": 80,
            "IpProtocol": "tcp",
            "IpRanges": [
                {"CidrIp": "0.0.0.0/0", "Description": "internet"},
            ],
        },
    ],
)

For more help, read How To Create And Configure An AWS VPC With Python.

jarmod
  • 71,565
  • 16
  • 115
  • 122
  • 1
    Man that bit of code is so much easier to understand and use and works fine too. Thanks jarmod once again. – xRasp Mar 02 '21 at 17:52
  • Do you also by chance know how to copy a .pem file from Ubuntu into the SSH as its saying no pem file found and I thought it would be an easy solution but doesn't seem to be working. All fine if not. – xRasp Mar 02 '21 at 18:24
  • Are you saying that you're trying ssh to your new Ubuntu instance but you don't have the PEM file? – jarmod Mar 02 '21 at 18:44
  • No it's when I SSH into my Instance using my PEM key it doesn't let me run any commands such as I went to copy something to my SSH Instance and it gave me this error. "Warning: Identity file AlexBpem.pem not accessible: No such file or directory. Permission denied (publickey,gssapi-keyex,gssapi-with-mic). lost connection" – xRasp Mar 02 '21 at 18:56
  • That sounds like exactly what I just asked. You're trying to SSH into the instance or remotely execute a command on the remote instance (which is effectively the same mechanism) and your SSH client reports that it can't find AlexBpem.pem. Check how you are supplying the PEM filename to your SSH client and that the file actually exists at the specified location. When you correct that, I'm guessing that you will run into additional issues so please read [this helpful article](https://docs.aws.amazon.com/quickstarts/latest/vmlaunch/step-2-connect-to-instance.html#sshclient). – jarmod Mar 02 '21 at 19:39
  • My bad, misunderstood what you meant but yeah you are exactly right. But when I go to transfer a file over to my Instance from my SSH it tells me that no right file or directory even after inputting the command " ssh -i AlexBpem.pem monitor.sh ec2-user@34.244.112.60:. " which isn't specifying a directory so I tried the ~/home/ubuntu/downloads etc to the file location and that didn't work and i'm not mis-spelling my key name file. – xRasp Mar 02 '21 at 19:48
  • Nevermind, got it working afterwards. All is fine. – xRasp Mar 02 '21 at 19:58