Creating AWS VPC using Ansible 2.0

Posted By : Ankit Arora | 24-Sep-2017

AWS is the public cloud we have been using for a long time. Setting up VPC is also important like setting up an EC2 instance based on the project requirement. Automation is the thing which makes it easy for us to work on cloud.


Few days ago, I faced a problem for deploying same AWS infrastructure architecture in seven different regions. Creating whole architecture would have been very difficult to deploy when we were left with very less time to meet the delivery dates.


To maintain the security of project, I decided to write an Ansible playbook to create VPC for the required project. Below is the playbook for creating VPC of a 3-tier architecture using Ansible. We will create subnets in multiple regions for the following:

    ELB(Public Subnet)
    App Server(Private Subnet)
    Redis Server(Private Subnet)
    DB Server(Private Subnet)


Prerequisites:

l Ansible 2.0: sudo apt-get install ansible

l AWS-CLI: sudo pip install awscli

l Boto: sudo pip install boto


Playbook structure will be:

    playbook.yml
    inventory
    vars.yml
    roles/
        vpc/
            tasks/
                main.yml

 

Now writing the main file i.e vpc-playbook.yml

 

---

- hosts: local

  roles:

    - vpc


Writing the inventory/host file.

    [local]

    localhost ansible_connection=local


Now, writing the vars.yml

    ---


    # AWS Credentials

    aws_access_key: "THISISMYAWSACCESSKEY"

    aws_secret_key: "ThisIsMyAwSSecretKey"

    aws_region:     "eu-west-1"


    # VPC Information

    vpc_name:       "My VPC"

    vpc_cidr_block: "10.0.0.0/16"


    # Subnets

    public_subnet_1_cidr:  "10.10.10.0/24"

    private_subnet_1_cidr: "10.10.30.0/24"

    public_subnet_2_cidr:  "10.10.20.0/24"

    private_subnet_2_cidr: "10.10.40.0/24"

 

Don’t forget to change AWS keys. I have created a new key pair for creating VPC which contains only VPC permissions so that I won’t reflect any other AWS service or data loss.


Now writing the roles/vpc/tasks/main.yml file.

    ---

    # 1st task : VPC creation.

    # Setting variables in vars.yml


    - name:               Create VPC

      ec2_vpc_net:

        name:             "{{ vpc_name }}"

        cidr_block:       "{{ vpc_cidr_block }}"

        region:           "{{ aws_region }}"

        aws_access_key:   "{{ aws_access_key }}"

        aws_secret_key:   "{{ aws_secret_key }}"

        state:            "present"

      register: my_vpc


    - name:               Set VPC ID in variable

      set_fact:

        vpc_id:           "{{ my_vpc.vpc.id }}"


    # Creating subnets in multi-AZs


    - name:               Create Public Subnet [AZ-1]

      ec2_vpc_subnet:

        state:            "present"

        vpc_id:           "{{ vpc_id }}"

        cidr:             "10.0.1.0/24"

        az:               "{{ aws_region }}a"

        region:           "{{ aws_region }}"

        aws_access_key:   "{{ aws_access_key }}"

        aws_secret_key:   "{{ aws_secret_key }}"

        resource_tags:

          Name:           "Public Subnet 1"

      register: my_public_subnet_az1


    - name:               Set Public Subnet ID in variable [AZ-1]

      set_fact:

        public_subnet_az1_id: "{{ my_public_subnet_az1.subnet.id }}"


    - name:               Create Private Subnet [AZ-1]

      ec2_vpc_subnet:

        state:            "present"

        vpc_id:           "{{ vpc_id }}"

        cidr:             "10.0.2.0/24"

        az:               "{{ aws_region }}a"

        region:           "{{ aws_region }}"

        aws_access_key:   "{{ aws_access_key }}"

        aws_secret_key:   "{{ aws_secret_key }}"

        resource_tags:

          Name:           "Private Subnet 1"

      register: my_private_subnet_az1


    - name:               Set Private Subnet ID in variable [AZ-1]

      set_fact:

        private_subnet_az1_id: "{{ my_private_subnet_az1.subnet.id }}"


    - name:               Create Public Subnet [AZ-2]

      ec2_vpc_subnet:

        state:            "present"

        vpc_id:           "{{ vpc_id }}"

        cidr:             "10.0.11.0/24"

        az:               "{{ aws_region }}b"

        region:           "{{ aws_region }}"

        aws_access_key:   "{{ aws_access_key }}"

        aws_secret_key:   "{{ aws_secret_key }}"

        resource_tags:

          Name:           "Public Subnet 2"

      register: my_public_subnet_az2


    - name:               Set Public Subnet ID in variable [AZ-2]

      set_fact:

        public_subnet_az2_id: "{{ my_public_subnet_az2.subnet.id }}"


    - name:               Create Private Subnet [AZ-2]

      ec2_vpc_subnet:

        state:            "present"

        vpc_id:           "{{ vpc_id }}"

        cidr:             "10.0.12.0/24"

        az:               "{{ aws_region }}b"

        region:           "{{ aws_region }}"

        aws_access_key:   "{{ aws_access_key }}"

        aws_secret_key:   "{{ aws_secret_key }}"

        resource_tags:

          Name:           "Private Subnet 2"

      register: my_private_subnet_az2


    - name:               Set Private Subnet ID in variable [AZ-2]

      set_fact:

        private_subnet_az2_id: "{{ my_private_subnet_az2.subnet.id }}"


    # Attaching Network gateway


    - name:               Create Internet Gateway for VPC

      ec2_vpc_igw:

        vpc_id:           "{{ vpc_id }}"

        region:           "{{ aws_region }}"

        aws_access_key:   "{{ aws_access_key }}"

        aws_secret_key:   "{{ aws_secret_key }}"

        state:            "present"

      register: my_vpc_igw


    - name:               Set Internet Gateway ID in variable

      set_fact:

        igw_id:           "{{ my_vpc_igw.gateway_id }}"


    # Creating 2 EIPs & attaching them to NAT gateways.


    - name: Setup AWS CLI (1/3)

      shell: >

        aws configure set aws_access_key_id "{{ aws_access_key }}"


    - name: Setup AWS CLI (2/3)

      shell: >

        aws configure set aws_secret_access_key "{{ aws_secret_key }}"


    - name: Setup AWS CLI (3/3)

      shell: >

        aws configure set region {{ aws_region }}


    - name: Create Elastic IP [AZ-1]

      shell: >

          aws ec2 allocate-address --domain vpc --query AllocationId | tr -d '"'

      register: eip_az1


    - name: Set EIP in variable [AZ-1]

      set_fact:

        my_eip_az1: "{{ eip_az1.stdout }}"


    - name: Create Elastic IP [AZ-2]

      shell: >

          aws ec2 allocate-address --domain vpc --query AllocationId | tr -d '"'

 

      register: eip_az2     - name: Set EIP in variable [AZ-2]       set_fact:         my_eip_az2: "{{ eip_az2.stdout }}"     # Creating NAT gateways     - name: Create NAT Gateway [AZ-1]       shell: >         aws ec2 create-nat-gateway \         --subnet-id {{ public_subnet_az1_id }} \         --allocation-id {{ my_eip_az1 }} \         --query NatGateway.NatGatewayId | tr -d '"'       register: my_nat_gateway_z1     - name: Set Nat Gateway ID in variable [AZ-1]       set_fact:         nat_gateway_az1_id: "{{ my_nat_gateway_z1.stdout }}"     - name: Create NAT Gateway [AZ-2]       shell: >         aws ec2 create-nat-gateway \         --subnet-id {{ public_subnet_az2_id }} \         --allocation-id {{ my_eip_az2 }} \         --query NatGateway.NatGatewayId | tr -d '"'       register: my_nat_gateway_z2     - name: Set Nat Gateway ID in variable [AZ-2]       set_fact:         nat_gateway_az2_id: "{{ my_nat_gateway_z2.stdout }}"     # Pausing few seconds for the NAT Gateways to be ready.     - pause: seconds=5     # Creating Public & Private Route Tables     - name: Set up public subnet route table       ec2_vpc_route_table:         vpc_id: "{{ vpc_id }}"         region: "{{ aws_region }}"         aws_access_key: "{{ aws_access_key }}"         aws_secret_key: "{{ aws_secret_key }}"         tags:           Name: "Public"         subnets:           - "{{ public_subnet_az1_id }}"

 

          - "{{ public_subnet_az2_id }}"         routes:           - dest: "0.0.0.0/0"             gateway_id: "{{ igw_id }}"     - name: Set up private subnet route table [AZ-1]       ec2_vpc_route_table:         vpc_id: "{{ vpc_id }}"         region: "{{ aws_region }}"         aws_access_key: "{{ aws_access_key }}"         aws_secret_key: "{{ aws_secret_key }}"         tags:           Name: "Private 1"         subnets:           - "{{ private_subnet_az1_id }}"         routes:           - dest: "0.0.0.0/0"             gateway_id: "{{ nat_gateway_az1_id }}"     - name: Set up private subnet route table [AZ-2]       ec2_vpc_route_table:         vpc_id: "{{ vpc_id }}"         region: "{{ aws_region }}"         aws_access_key: "{{ aws_access_key }}"         aws_secret_key: "{{ aws_secret_key }}"         tags:           Name: "Private 2"         subnets:           - "{{ private_subnet_az2_id }}"         routes:           - dest: "0.0.0.0/0"             gateway_id: "{{ nat_gateway_az2_id }}"

 

Running the playbook:

    ansible-playbook vpc-playbook.yml -i host -e @vars.yml

 

About Author

Author Image
Ankit Arora

Ankit is a Redhat Certified Engineer and Cloud Engineer.

Request for Proposal

Name is required

Comment is required

Sending message..