--- type: article wp_id: 596 title: 'AWS CLI | VPC, Subnets, EC2, and more' date: '2020-11-28T19:47:00' slug: 'aws-cli-vpc-subnets-ec2-and-more' image: name: 'aws-cli-vpc-subnets-ec2-and-more.png' width: 1280 height: 720 status: 'published' description: 'Let’s take a look at how to use the aws cli to create a VPC, Subnets, EC2 instances, and more.' tags: ['aws', 'cloud computing', 'iac', 'infrastructure as code', 'ec2', 'vpc', 'aws cli', 'aws cli vpc', 'aws cli ec2', 'aws cli subnets', 'aws cli security groups', 'aws cli internet gateway', 'aws cli route table', 'aws cli create vpc', 'aws cli create subnet', 'aws cli create ec2 instance', 'aws cli create internet gateway', 'aws cli create route table', 'aws cli create security group', 'aws cli create security groups', 'aws cli create'] --- Let’s take a look at how to use the aws cli to create a VPC, Subnets, EC2 instances, and more. In this article, we will take a look at how to do the following using the aws cli: * Create a VPC and subnets * Create an internet gateway and route table to make the subnet public * Create security groups * Create an ec2 instance on a public subnet and install nginx Skip to the bottom of the article if you just want the script. ## AWS CLI The AWS Command Line Interface (CLI) lets us manage all of our AWS services from the command line, without having to use the web console. So instead of clicking a bunch of buttons to create a new EC2 instance, you could just run a command like this: ```shell aws ec2 run-instances --region $region --image-id "ami-0d4504aaac331dc68" --count 1 --instance-type t2.micro --associate-public-ip-address ``` In this article, we will take a look at how to setup an S3 bucket to host a static website using the aws cli. Skip to the bottom of the article if you just want the script. ## Setup If you haven’t setup the AWS CLI already, you can do so using this link: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html The reference for all of the commands used here is available at https://docs.aws.amazon.com/cli/latest/reference/ ## VPC and EC2 instance When setting up a new VPC to deploy EC2 instances, we usually follow these basic steps. 1. Create a vpc 2. Create subnets for different parts of the infrastructure 3. Create a route table for a public subnet 4. Attach an internet gateway to make a public subnet 5. Create security groups to allow specific traffic 6. Create ec2 instances on the subnets ### 1\. Create a vpc [aws ec2 create-vpc](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-vpc.html) ```shell aws ec2 create-vpc --region us-east-1 --cidr-block "10.0.0.0/16" ``` This will setup a new VPC with the cidr block `10.0.0.0/16` and return some JSON. You will need to find the `VpcId` from this JSON and save it for the next steps. ```json { "Vpc": { "VpcId": "vpc-2f09a348", ... } } ``` ### 2\. Create subnets for different parts of the infrastructure [aws ec2 create-subnet](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-subnet.html) ```shell aws ec2 create-subnet --region us-east-1 --cidr-block "10.0.1.0/24" --availability-zone us-east-1a --vpc-id "..." aws ec2 create-subnet --region us-east-1 --cidr-block "10.0.2.0/24" --availability-zone us-east-1b --vpc-id "..." ``` This will create two new subnets in az 1a an 1b with the cidr blocks `10.0.1.0/24` and `10.0.w.0/24`. You will need to use the VpcId from the previous step. Find the `SubnetId` from the json returned and save them for the next steps. We will use the first subnet in us-east-1a as the public subnet, so we really only need the id of that subnet. ```json { "Subnet": { ... "SubnetId": "subnet-079a1cf", ... } } ``` ### 3\. Create a route table for a public subnet [aws ec2 create-route-table](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-route-table.html) ```shell aws ec2 create-route-table --region us-east-1 --vpc-id "..." ``` This will create a new route table. You will need to use the VpcId from the first step. Find the `RouteTableId` from the json returned and save it for the next steps. ```json { "RouteTable": { ... "RouteTableId": "rtb-c1c8faa6", ... } } ``` [aws ec2 associate-route-table](https://docs.aws.amazon.com/cli/latest/reference/ec2/associate-route-table.html) ```shell aws ec2 associate-route-table --region us-east-1 --route-table-id "..." --subnet-id "..." ``` This will associate the route table with a VPC. You will need to use the VpcId from the first step and the first subnet id from earlier. ### 4\. Attach an internet gateway to make a public subnet [aws ec2 create-internet-gateway](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-internet-gateway.html) ```shell aws ec2 create-internet-gateway --region us-east-1 ``` This creates an internet gateway and does nothing else. We will still need to attach it to the VPC and route internet traffic to it. Find the `InternetGatewayId` from the returned json and save it for the next steps. ```json { "InternetGateway": { ... "InternetGatewayId": "igw-07d58174", ... } } ``` [aws ec2 attach-internet-gateway](https://docs.aws.amazon.com/cli/latest/reference/ec2/attach-internet-gateway.html) ```shell aws ec2 attach-internet-gateway --region us-east-1 --internet-gateway-id "..." --vpc-id "..." ``` This will attach it to the vpc. [aws ec2 create-route](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-route.html) ```shell aws ec2 create-route --region us-east-1 --route-table-id "..." --destination-cidr-block "0.0.0.0/0" --gateway-id "..." ``` This will route internet traffic through the gateway. At this point the VPC is setup in a good state. We can setup an EC2 instance on the public subnet and install a web server. ### 5\. Create security groups to allow specific traffic Before we setup a new EC2 instance on the public subnet, we need to create a security group that allows internet traffic on port 80 and 22. [aws ec2 create-security-group](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-security-group.html) ```shell aws ec2 create-security-group --region us-east-1 --description "Allow http access over the internet" --group-name "public-sg" --vpc-id "..." ``` This will create a security group, and nothing else. Save the `GroupId` from the json. ```json { "GroupId": "sg-e1fb8c9a" } ``` [aws ec2 authorize-security-group-ingress](https://docs.aws.amazon.com/cli/latest/reference/ec2/authorize-security-group-ingress.html) ```shell aws ec2 authorize-security-group-ingress --region us-east-1 --group-id "..." --protocol "tcp" --port "80" --cidr "0.0.0.0/0" aws ec2 authorize-security-group-ingress --region us-east-1 --group-id "..." --protocol "tcp" --port "22" --cidr "0.0.0.0/0" ``` This will allow all network traffic on port 80 and 22 (HTTP and SSH) for the security group we just created. ### 6\. Create ec2 instances on the subnets Time to deploy an EC2 instance. If you already have an ssh keypair setup, you can just use that and skip the next step. If you haven’t, or if you want to setup a new ssh key for this instance, run the following command. [aws ec2 create-key-pair](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-key-pair.html) ```shell aws ec2 create-key-pair --key-name MyKeyPair --query 'KeyMaterial' --output text > ~/.ssh/MyKeyPair.pem chmod 400 ~/.ssh/MyKeyPair.pem ``` This will generate a new keypair and store the private key on your machine at `~/.ssh/MyKeyPair.pem` [aws ec2 run-instances](https://docs.aws.amazon.com/cli/latest/reference/ec2/run-instances.html) ```shell # ami-04d29b6f966df1537 = Amazon Linux 2 aws ec2 run-instances \ --region us-east-1 \ --image-id "ami-04d29b6f966df1537" \ --count 1 \ --instance-type t2.micro \ --subnet-id "..." \ --security-group-ids "..." \ --associate-public-ip-address \ --key-name "..." \ --user-data = " #!/bin/bash -ex amazon-linux-extras install nginx1 echo \"