7 months, 1 week

Automating AWS Cloud Networking Infrastructure



When dealing with AWS programmatically using the boto3 SDK, we will use two different credentials, an Access Key ID and a Secret Key, to authenticate against the API.You can install the newest version of boto3 using python3 -m pip install boto3. 
Follow these steps to create the credentials you are going to use for authenticating your requests from the SDK:
1. Open the AWS console by accessing console.aws.amazon.com and authenticating using your username/password combination.
2. Navigate to your user's security credentials.
3. On the Your Security Credentials page, navigate to the Access keys section and click on Create New Access Key to generate a new key pair.
4. You'll be presented with a pop-up that shows your newly created Access Key ID and Secret Access Key. You can either save them by copying the information from the page or by clicking the Download Key File button. Take note of your Secret Access Key. 

Collecting information about your cloud networking resources
Follow these steps to programmatically retrieve all the VPCs and their associated EC2 instances:
1. Import the boto3 library:
import boto3
2. Set up the ec2 client from boto3:
ec2 = boto3.client('ec2')
3. First, retrieve all the VPCs:
vpc_data = ec2.describe_vpcs()
4. Then, iterate over all the VPCs:
for v in vpc_data['Vpcs']:
   print(f"VPC Id: {v['VpcId']}")
5. Filter for all EC2 instances associated with this VPC by providing a Filters argument:
 instance_data = ec2.describe_instances(Filters=[ {
 "Name": "vpc-id",
 "Values": [
 ] }
6. Check if we have active reservations:
 if len(instance_data['Reservations']) > 0:
7. Then, iterate over all the active Reservations groups:
 for res_num in range(0, len(instance_data['Reservations'])):
8. Finally, retrieve all the instances in that reservation group and display some information for that instance:
 for i in instance_data['Reservations'][res_num].get('Instances', []):
      print(f"- {i['InstanceType']} launched at {i['LaunchTime']}")

A full list of available functions can be found in the following documentation: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html
There is  a table containing the names and descriptions of the returned keys. You can find this list in the following documentation:
A list of all the filters is available in the following documentation: 

Starting EC2 instances
Follow these steps to launch an EC2 instance from your Python script:
1. Import the boto3 library:
import boto3
2. Create an ec2 resource:
ec2 = boto3.resource('ec2')
3. Next, we need to specify what kind of instance we would like to launch and what key-pair can be used for SSH authentication. Have a look at the How it 
works… section for a (non-comprehensive) list of available images:
KEY_PAIR = "<Insert key-pair name here>"
IMAGE_ID = "<Insert image id here>"
NUM_INSTANCES = <Insert number of instances>
4. With our information specified, we can create our new instance:
i = ec2.create_instances(ImageId=IMAGE_ID,
5. Finally, print out the instance:

A client is a low-level abstraction that is shared between the SDK and the AWS CLI tool. A client maps all the operations provided by the AWS API one to one and returns the JSON information that's retrieved from the API. A resource, on the other hand, is a boto3-specific abstraction that builds on top of a client and exposes the information in an object-oriented format. (A resource is a high-level abstraction that provides additional abstractions and functionalities.)

Virtual private cloud
VPC is an AWS service that lets you create separate and isolated environments for your resources to run in. In fact, every EC2 instance you start is part of your default VPC, but creating and then associating an EC2 instance with a specific VPC allows you to have full control over routing tables, internal IP addresses, and all other aspects of your instance's connectivity. 
Follow these steps to create a VPC programmatically:
1. Import the boto3 library:
import boto3
2. Create a new EC2 resource. VPCs are logically grouped in the EC2 section:
ec2_resource = boto3.resource('ec2')
3. Create a new VPC for the CIDR(Classless Inter-Domain Routing) block:
vpc = ec2_resource.create_vpc(CidrBlock='')
4. Wait until the VPC resource has been created:
5. Finally, print out the ID of our newly created VPC:
print(f"Created vpc {vpc.id}")

CIDR block —Classless Inter-Domain Routing. An internet protocol address allocation and route aggregation methodology.

Subnets allow you to further specify the routing and accessibility of your EC2 resources. 
You can create this key pair in the console. You can find a guide on how to do this at 
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html .

Follow these steps to create a new subnet and start an EC2 instance within it:
1. Import the boto3 library:
import boto3
2. Define the key pair and image ID that our EC2 instance will use:
KEY_PAIR = "<Insert your key pair name here>"
IMAGE_ID = "ami-07f1463af4eef577a"
3. Next, create an ec2 resource with our boto3 library:
ec2_resource = boto3.resource('ec2')
4. Then, create a new VPC that our subnet will be a part of:
vpc = ec2_resource.create_vpc(CidrBlock='')
print(f"Created vpc {vpc.id}")
5. Next, create a new subnet. The subnet's CIDR block needs to be a part of the IP block we've defined for our VPC:
subnet = vpc.create_subnet(CidrBlock='')
6. With our subnet created, we can define the network interface of our EC2 instance, which will be part of the newly created subnet:
net_inf = []
 'SubnetId': subnet.id,
 'DeviceIndex': 0
7. With the interface defined, we can go ahead and create our EC2 instance:
i = ec2_resource.create_instances(ImageId=IMAGE_ID,
8. Finally, print out the ID of our instance:
print(f"Instance with id {i[0].id} created")

Changing routes in your VPC
AWS uses the concept of routing tables and routes, all of which can be configured programmatically. 
Follow these steps to create a new route in your VPC:
1. Import the boto3 library:
import boto3
2. Let's start by defining the destination CIDR that we want our route to be valid for:
3. Next, create an ec2 resource from boto3:
ec2_resource = boto3.resource('ec2')
4. Create a new VPC and print out the VPC's ID for debugging:
vpc = ec2_resource.create_vpc(CidrBlock='')
print(f"Created vpc {vpc.id}")
5. Create a new subnet and print out that ID as well:
subnet = vpc.create_subnet(CidrBlock='')
print(f"Created subnet {subnet.id}")
6. Define a new gateway and attach the newly created internet gateway to our VPC:
gateway = ec2_resource.create_internet_gateway()
print(f"Created gateway {gateway.id} and associated with {vpc.id}")
7. Create a new route table within our VPC and associate the route table with our previously created subnet:
route_table = ec2_resource.create_route_table(VpcId=vpc.id)
print(f"Created route table {route_table.id}")
8. Finally, create a new route from our Destination block and associate the internet gateway we created previously:
r = route_table.create_route(DestinationCidrBlock=DST_CIDR, GatewayId=gateway.id)
print(f"Created route {r} for {DST_CIDR} block")