Nuxtstop

For all things nuxt.js

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

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

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 secure and isolated private network. If you have a plan to use AWS resources, 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 as Virtual Private Cloud (VPC) instead of using the default one.

More about VPC, click here!

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

  1. VPC in a region (me: ap-southeast-3 or Indonesia);
  2. Subnet on each AZ (3 in total);
  3. Internet gateway;
  4. Route table;
  5. Security group.

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

Alright, just like my previous posts. We'll use localhost as the target host, because here we don't touch EC2 instances yet. Make sure you've installed:

  1. AWS CLI and setup at least one credential;
  2. Ansible;
  3. Ansible collection for AWS by running ansible-galaxy collection install community.aws.

Note*: All details below, you can replace with your own value if you already prepared.

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 network 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 we register it on the VPC creation (Step 1) above.

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 create a local route. Then, to have an internet connection we should add a route with destination (anywhere) through Internet Gateway.

Note*: You can choose which subnets will be given internet connection. In this case, we'll make them all as 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've already decided which ports to be allowed for our EC2 instance, let's make it too under our VPC. Cause the default one is under default VPC. For instance, I'll host web servers using EC2 instances. So, I'll allow port 22 for remote and 80 to access the web servers.

    - 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'll not billed for what we've created above. Don't worry! If you want to delete them all, we'll do it at the end cause we still need it for our EC2 instances next.

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

References:
https://docs.ansible.com/ansible/latest/collections/amazon/aws/ec2_vpc_net_module.html
https://docs.ansible.com/ansible/latest/collections/amazon/aws/ec2_vpc_subnet_module.html
https://docs.ansible.com/ansible/devel/collections/amazon/aws/ec2_vpc_route_table_module.html
https://docs.ansible.com/ansible/latest/collections/amazon/aws/ec2_vpc_igw_module.html
https://docs.ansible.com/ansible/latest/collections/amazon/aws/ec2_group_module.html