Skip to content

aws sysops 03 cli ec2 vpc

ebarault edited this page May 16, 2017 · 5 revisions

Using the AWS CLI to manage EC2 VPCs and subnets

AWS CLI EC2 reference

Step 1: Create a VPC and Subnets

Create a VPC with a 10.0.0.0/16 CIDR block.

$ aws ec2 create-vpc --cidr-block 10.0.0.0/16
{
    "Vpc": {
        "VpcId": "vpc-e8099680",
        "InstanceTenancy": "default",
        "Tags": [],
        "Ipv6CidrBlockAssociationSet": [],
        "State": "pending",
        "DhcpOptionsId": "dopt-a9548fc1",
        "CidrBlock": "10.0.0.0/16",
        "IsDefault": false
    }
}

Note the VpcId: vpc-e8099680

Create a subnet with a 10.0.0.0/24 CIDR block.

$ aws ec2 create-subnet --vpc-id vpc-e8099680 --cidr-block 10.0.0.0/24
{
    "Subnet": {
        "VpcId": "vpc-e8099680",
        "AvailableIpAddressCount": 251,
        "MapPublicIpOnLaunch": false,
        "DefaultForAz": false,
        "Ipv6CidrBlockAssociationSet": [],
        "State": "pending",
        "AvailabilityZone": "eu-central-1a",
        "SubnetId": "subnet-7b114a13",
        "CidrBlock": "10.0.0.0/24",
        "AssignIpv6AddressOnCreation": false
    }
}

Create a second subnet with a 10.0.1.0/24 CIDR block.

$ aws ec2 create-subnet --vpc-id vpc-e8099680 --cidr-block 10.0.1.0/24
{
    "Subnet": {
        "VpcId": "vpc-e8099680",
		...
    }
}

Step 2: Make one Subnet Public

To make one of the subnets public and give it access to Internet, we need:

  • attach an Internet gateway to the VPC
  • create a custom route table
  • configure routing for the subnet to the Internet gateway

Create an Internet gateway and attach the VPC to it

$ aws ec2 create-internet-gateway
{
    "InternetGateway": {
        "Tags": [],
        "InternetGatewayId": "igw-54988f3d",
        "Attachments": []
    }
}

Note the InternetGatewayId: igw-54988f3d

$ aws ec2 attach-internet-gateway --vpc-id vpc-e8099680 --internet-gateway-id igw-54988f3d
# The command does not return anything

Create a routing table and a default route to the Internet gateway

$ aws ec2 create-route-table --vpc-id vpc-e8099680
{
    "RouteTable": {
        "Associations": [],
        "RouteTableId": "rtb-5a095d32",
        "VpcId": "vpc-e8099680",
        "PropagatingVgws": [],
        "Tags": [],
        "Routes": [
            {
                "GatewayId": "local",
                "DestinationCidrBlock": "10.0.0.0/16",
                "State": "active",
                "Origin": "CreateRouteTable"
            }
        ]
    }
}

NOTE:

  • The first Routing Table created for a VPC is elected the VPC's Main Routing Table
  • Any subnet which is not specifically associated with a Routing Table uses the Main Routing Table of the VPC
  • Our 2 new subnets will hence use the Routing Table we just created as their default

Note the RouteTableId: rtb-5a095d32

$ aws ec2 create-route --route-table-id rtb-5a095d32 --destination-cidr-block 0.0.0.0/0 --gateway-id igw-54988f3d
{
    "Return": true
}

Confirm the new route has been created using the describe-route-tables command:

$ aws ec2 describe-route-tables --route-table-id rtb-5a095d32
{
    "RouteTables": [
        {
            "Associations": [],
            "RouteTableId": "rtb-5a095d32",
            "VpcId": "vpc-e8099680",
            "PropagatingVgws": [],
            "Tags": [],
            "Routes": [
                {
                    "GatewayId": "local",
                    "DestinationCidrBlock": "10.0.0.0/16",
                    "State": "active",
                    "Origin": "CreateRouteTable"
                },
                {
                    "GatewayId": "igw-54988f3d",
                    "DestinationCidrBlock": "0.0.0.0/0",
                    "State": "active",
                    "Origin": "CreateRoute"
                }
            ]
        }
    ]
}

Now list the VPC's Subnets to get their SubnetIds

$ aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-e8099680"

Go further!

  • This command returns a lot of information, how would you use the --query` parameter to only fetch SubnetId and CidrBlock for each subnet and show the result as a table?
$ aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-e8099680" --query 'Subnets[*].{SubnetId:SubnetId,CidrBlock:CidrBlock}' --output table
------------------------------------
|          DescribeSubnets         |
+--------------+-------------------+
|   CidrBlock  |     SubnetId      |
+--------------+-------------------+
|  10.0.1.0/24 |  subnet-d01249b8  |
|  10.0.0.0/24 |  subnet-7b114a13  |
+--------------+-------------------+

Choose one subnet and note the SubnetId: subnet-7b114a13

Associate the route table with the subnet

$ aws ec2 associate-route-table --subnet-id subnet-7b114a13 --route-table-id rtb-5a095d32
{
    "AssociationId": "rtbassoc-ec4e8c87"
}

NOTE:

  • We now modify the public IP addressing behavior of the public subnet with the --map-public-ip-on-launch command so that an instance launched into the subnet automatically receives a public IP address, otherwise we should associate an Elastic IP address to the instance.
$ aws ec2 modify-subnet-attribute --subnet-id subnet-7b114a13 --map-public-ip-on-launch
# The command does not return anything

Launch and connect to an instance in the public subnet

First we create a security group in the VPC with a rule that allows SSH access from anywhere:

$ aws ec2 create-security-group --group-name SSHAccess --description "Security group for SSH access" --vpc-id vpc-e8099680
{
    "GroupId": "sg-bdc64dd6"
}

Note the Security GroupId: sg-bdc64dd6

Then we create the rule for SSH access from anywhere:

$ aws ec2 authorize-security-group-ingress --group-id sg-bdc64dd6 \
  --protocol tcp --port 22 --cidr 0.0.0.0/0
# The command does not return anything

Next, we launch an instance into the public subnet:

$ aws ec2 run-instances --image-id ami-060cde69 --count 1 --instance-type t2.micro \
  --key-name sysops --security-group-ids sg-bdc64dd6 --subnet-id subnet-7b114a13
# ami-060cde69 is AWS image for Ubuntu 16.04

Note the InstanceId: i-0ca725b4fbe6af75e

Before connecting to the newly created instance, let's confirm it is up and running.

$ aws ec2 describe-instances --instance-id i-0ca725b4fbe6af75e --query 'Reservations[*].Instances[*].{id:InstanceId, zone: Placement.AvailabilityZone, status: State.Name, publicIpv4: PublicIpAddress}'
[
    [
        {
            "status": "running",
            "publicIpv4": "52.59.17.117",
            "id": "i-0ca725b4fbe6af75e",
            "zone": "eu-central-1a"
        }
    ]
]

Note the publicIpv4: 52.59.17.117

Finally connect to the instance in the public network to confirm your setup is OK and the instance has access to Internet:

$ ssh -i "sysops.pem" [email protected]
# NOTE: login as user ec2-user if you launched an Amazon Linux AMI instance

🎉🎉🎉 tada!

Clean Up (Optional)

# instances
$ aws ec2 terminate-instances --instance-ids i-0ca725b4fbe6af75e

# security group
$ aws ec2 delete-security-group --group-id sg-bdc64dd6

# subnets
$ aws ec2 delete-subnet --subnet-id subnet-7b114a13
$ aws ec2 delete-subnet --subnet-id subnet-d01249b8

# route table
aws ec2 delete-route-table --route-table-id rtb-5a095d32

# internet gateway
$ aws ec2 detach-internet-gateway --internet-gateway-id igw-54988f3d --vpc-id vpc-e8099680
$ aws ec2 delete-internet-gateway --internet-gateway-id igw-54988f3d

# vpc
$ aws ec2 delete-vpc --vpc-id vpc-e8099680

Clone this wiki locally