DEV Community

Nurul Ramadhona for AWS Community Builders

Posted on • Updated on

Build Your Own Default Amazon VPC (Virtual Private Cloud) Using Ansible

Just like when we have an on-premise model for our infrastructure, we also need a network for our cloud infrastructure either public or private. Yes, we can build a secure and isolated private network. If you have a plan to use AWS resources or let's say you want to host your servers using EC2 instances! Then you can create your own network for them or on AWS it's called a Virtual Private Cloud (VPC), instead of using the default one.

More about VPC, click here!

In this section, we will create a VPC to connect our EC2 instances placed in different AZs and give them an internet connection. From this scenario, we will need:

  1. VPC in a region (me: ap-southeast-3);

  2. Subnet on each AZ (3 in total);

  3. Internet gateway;

  4. Route table;

  5. Security group.

VPC

Then, I won't go through the console but I'll use Ansible instead. Why? If you have ever seen my previous posts, you should know why :)

Alright! Just like my previous posts, we will use localhost as the target host cause here we don't touch EC2 instances yet. Make sure you have installed:

  1. AWS CLI and set at least one credential;

  2. Ansible;

  3. Ansible collection for AWS by running ansible-galaxy collection install amazon.aws and ansible-galaxy collection install community.aws.

Note*: You can replace all the details below with your own values if you already prepared them.

Inventory: host.yml

---

localhost:
  hosts:
    127.0.0.1:
Enter fullscreen mode Exit fullscreen mode

Playbook: vpc.yml

- name: vpc
  hosts: localhost
  connection: local
  gather_facts: no
  tasks:
Enter fullscreen mode Exit fullscreen mode

1. Create a VPC

    - name: create vpc
      amazon.aws.ec2_vpc_net:
        name: custom_vpc
        cidr_block: 10.0.0.0/16
        region: ap-southeast-3
      register: vpc
Enter fullscreen mode Exit fullscreen mode

2. Create Subnets

Make sure all subnets are included in the same VPC network range but in different networks between subnets)

  • Availability Zone A
    - name: create subnet for first az
      amazon.aws.ec2_vpc_subnet:
        vpc_id: "{{ vpc.vpc.id }}"
        state: present
        az: ap-southeast-3a
        cidr: 10.0.1.0/28
      register: az1_apse3
Enter fullscreen mode Exit fullscreen mode
  • Availability Zone B
    - name: create subnet for second az
      amazon.aws.ec2_vpc_subnet:
        vpc_id: "{{ vpc.vpc.id }}"
        state: present
        az: ap-southeast-3b
        cidr: 10.0.2.0/28
      register: az2_apse3
Enter fullscreen mode Exit fullscreen mode
  • Availability Zone C
    - name: create subnet for third az
      amazon.aws.ec2_vpc_subnet:
        vpc_id: "{{ vpc.vpc.id }}"
        state: present
        az: ap-southeast-3c
        cidr: 10.0.3.0/28
      register: az3_apse3
Enter fullscreen mode Exit fullscreen mode

Note*: The vpc variable is only available or defined when all related tasks are executed concurrently at once.

3. Create Internet Gateway

    - name: create internet gateway
      amazon.aws.ec2_vpc_igw:
        vpc_id: "{{ vpc.vpc.id }}"
        state: present
      register: igw
Enter fullscreen mode Exit fullscreen mode

4. Create Route Table

When we create a VPC, a (main) route table will be created along with it but it only creates a local route. Then, to get an internet connection we should add a route with a quad-zero route as the destination for an unspecified address (anywhere) through Internet Gateway.

Note*: You can choose which subnets will be given an internet connection that acts as a public subnet.

    - name: create custom route table
      amazon.aws.ec2_vpc_route_table:
        vpc_id: "{{ vpc.vpc.id }}"
        region: ap-southeast-3
        subnets:
          - "{{ az1_apse3.subnet.id }}"
          - "{{ az2_apse3.subnet.id }}"
          - "{{ az3_apse3.subnet.id }}"
        routes:
          - dest: 0.0.0.0/0
            gateway_id: "{{ igw.gateway_id }}"
Enter fullscreen mode Exit fullscreen mode

5. Create Security Group

If you have already decided whether any ports will be allowed for our EC2 instances, add them under the new VPC because the default one is placed under the default VPC. For example, I'll host a web server using an EC2 instance. So, I'll allow port 22 to remote the host and 80 to access the web server.

    - name: create security group
      amazon.aws.ec2_group:
        name: ssh-web
        description: allow ssh and http
        vpc_id: "{{ vpc.vpc.id }}"
        region: ap-southeast-3
        rules:
          - proto: tcp
            ports: 22
            cidr_ip: 0.0.0.0/0
          - proto: tcp
            ports: 80
            cidr_ip: 0.0.0.0/0
Enter fullscreen mode Exit fullscreen mode

Run the playbook!

$ ansible-playbook -i host.yml vpc.yml

PLAY [vpc] **************************************************************************************************************************************************************

TASK [create vpc] *******************************************************************************************************************************************************
changed: [127.0.0.1]

TASK [create subnet for first az] ***************************************************************************************************************************************
changed: [127.0.0.1]

TASK [create subnet for second az] **************************************************************************************************************************************
changed: [127.0.0.1]

TASK [create subnet for third az] ***************************************************************************************************************************************
changed: [127.0.0.1]

TASK [create internet gateway] ******************************************************************************************************************************************
changed: [127.0.0.1]

TASK [create custom route table] ****************************************************************************************************************************************
changed: [127.0.0.1]

TASK [create security group] ********************************************************************************************************************************************
changed: [127.0.0.1]

PLAY RECAP **************************************************************************************************************************************************************
127.0.0.1                  : ok=7    changed=7    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Enter fullscreen mode Exit fullscreen mode

Let's check!

$ aws ec2 describe-vpcs --query 'Vpcs[?Tags[?Value==`custom_vpc`]].{VPC:VpcId, CIDR:CidrBlock}'
[
    {
        "VPC": "vpc-0a6bbb5ca26b09679",
        "CIDR": "10.0.0.0/16"
    }
]
Enter fullscreen mode Exit fullscreen mode
$ aws ec2 describe-subnets --query 'Subnets[?VpcId==`vpc-0a6bbb5ca26b09679`].{AZ:AvailabilityZone, CIDR:CidrBlock, SubnetID:SubnetId}'
[
    {
        "AZ": "ap-southeast-3c",
        "CIDR": "10.0.3.0/28",
        "SubnetID": "subnet-00b4e72d63a2125de"
    },
    {
        "AZ": "ap-southeast-3a",
        "CIDR": "10.0.1.0/28",
        "SubnetID": "subnet-0276d466994fa3087"
    },
    {
        "AZ": "ap-southeast-3b",
        "CIDR": "10.0.2.0/28",
        "SubnetID": "subnet-07bb6501337e4f87b"
    }
]
Enter fullscreen mode Exit fullscreen mode

Note*: Since VPC is not used yet and it doesn't cause availability risks or bandwidth constraints on our network traffic, we won't be billed for what we have created above. Don't worry! If you want to delete them all, we will do it at the end of this series cause we still need them for our EC2 instances next.

That's it for the VPC! We will use this VPC to launch EC2 instances. Let's move to the next post!

References:

Top comments (0)