DMCA.com Protection Status Trending Topics About Devops

Sunday, 5 September 2021

Ansible Project 1

 In this tutorial, we are going to create a VPC using Ansible in AWS. Our VPC will include a router, subnet, IGW, Security Group and definitely an EC2 instance.

This is the topology we would create. (I have mentioned the Ansible Module so as to make it easier)

Prerequisites

  • IAM User with the required permission.
  • Boto installed. (Ansible uses the Boto Python library to handle AWS management)

If you are planning to improve your IAM security, please read my guide on it.

1. Creating a custom Role

We would first create an AWS VPC Role.

1
ansible-galaxy init aws-vpc

We would be using the two files below from our aws-vpc role.

1
2
3
4
- tasks
   - main.yml
- vars
   -main.yml

Variables

We will place the variables in the vars/main.yml file. This allows the role to be easily reusable. Modify the variables depending on your requirement but replace your AWS Access and Secret key.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
---
#vars/main.yml
 
aws_access_key: ""
aws_secret_key: ""
region: "us-east-1"
 
# VPC
vpc_cidr: 10.10.0.0/24
vpc_name: "Ansible VPC"
 
# Subnet
subnet_name: "Ansible Subnet"
subnet_cidr: 10.10.0.0/26
 
# Internet Gateway Name
igw_name: "Traffic IGW"
 
securitygroup_name: "Ansible Security Group"
 
ec2_tag: "WebServer"
 
#The local path to which we would save our EC2 Private Key
ec2_key_directory: "/home/ansible/roles/aws-vpc/"
keypair_name: "ec2_key_pair"

Do not store your AWS credentials as a variable! Follow the best practice

2. Creating the VPC

Our VPC will include the following components.

  • VPC
  • Subnet
  • Router
  • IGW (Internet Gateway)
  • Security Group
  • EC2 Instance

We will write all the code below in the tasks/main.yml file.

a) VPC

To create a VPC, we have to use the ec2_vpc_net module. We will register the module returned data in the “vpc” variable.

1
2
3
4
5
6
7
8
9
- name: create VPC
  ec2_vpc_net:
    name: "{{ vpc_name }}"
    cidr_block: "{{ vpc_cidr }}"
    region: "{{ region }}"
    state: present
    aws_access_key: "{{ aws_access_key }}"
    aws_secret_key: "{{ aws_secret_key }}"
  register: vpc

b) Creating a subnet and associating it with an Internet Gateway

Now that we have successfully created a VPC. We would need to create a subnet and an IGW. We need an IGW so that our public subnet can access the internet.

In our subnet, we have set map_public to “YES”. This means instances created in this subnet is associated with a public IP address.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- name: associate subnet to the VPC
  ec2_vpc_subnet:
   state: present
   vpc_id: "{{ vpc_id }}"
   region: "{{ region }}"
   cidr: "{{ subnet_cidr }}"
   aws_access_key: "{{ aws_access_key }}"
   aws_secret_key: "{{ aws_secret_key }}"
   map_public: yes
   resource_tags:
     Name: "{{ subnet_name }}"
  register: subnet
 
- name: create IGW
  ec2_vpc_igw:
   vpc_id: "{{ vpc_id }}"
   region: "{{ region }}"
   aws_access_key: "{{ aws_access_key }}"
   aws_secret_key: "{{ aws_secret_key }}"
   state: "present"
   tags:
     Name: "{{ igw_name }}"
  register: igw

c) Routing traffic to IGW and creating a security group

Now, we would need to route the traffic to the IGW via the route table and create a security group.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
- name: Route IGW
   ec2_vpc_route_table:
    vpc_id: "{{ vpc_id }}"
    region: "{{ region }}"
    aws_access_key: "{{ aws_access_key }}"
    aws_secret_key: "{{ aws_secret_key }}"
    subnets:
      - "{{ subnet.subnet.id }}"
    routes:
      - dest: 0.0.0.0/0
        gateway_id: "{{ igw.gateway_id  }}"
    tags:
      Name: "{{ route_name }}"
 
# update the CIDR address in the SSH port section.
 
 - name: Create Security Group
   ec2_group:
    name: Web DMZ
    description: DMZ Security Group
    vpc_id: "{{ vpc_id }}"
    region: "{{ region }}"
    aws_access_key: "{{ aws_access_key }}"
    aws_secret_key: "{{ aws_secret_key }}"
    rules:
      - proto: tcp
        ports:
        - 80
        cidr_ip: 0.0.0.0/0
      - proto: tcp
        ports:
        - 22
        cidr_ip: 0.0.0.0/0
   register: security_group

d) Creating an EC2 Key Pair and an EC2 instance

This is our last step, we will create an EC2 Key Pair and an EC2 instance.

Key points:

  • if you already have an EC2 key pair, skip the EC2 key pair and update the key_name with the name of the key pair.
  • exact_count is important! It determines the number of instances is created.
  • Image ID can be found on AWS Marketplace.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- name: create a new ec2 key pair
   ec2_key:
    aws_access_key: "{{ aws_access_key }}"
    aws_secret_key: "{{ aws_secret_key }}"
    name: ec2_keypair
    region: "{{ region }}"
   register: keypair
 
- name: Copy EC2 Private Key locally so it can be later on used to SSH into the instance
  copy: content="{{ keypair.key.private_key }}" dest={{ ec2_key_directory }}key.ppk
  when: keypair.changed == true
 
 - name: Create EC2 server
   ec2:
    image: ami-467ca739
    wait: yes
    instance_type: t2.micro
    region: "{{ region }}"
    group_id: "{{ security_group.group_id }}"
    vpc_subnet_id: "{{ subnet.subnet.id }}"
    key_name: "{{ keypair.key.name  }}"
    count_tag:
      Name: apacheserver
    exact_count: 1
    aws_access_key: "{{ aws_access_key }}"
    aws_secret_key: "{{ aws_secret_key }}"

This creates a simple VPC but creating a complex VPC is still achievable with Ansible, as it provides all the necessary modules for a VPC creation in the AWS.

Saturday, 4 September 2021

Remove volume via ansible

 - hosts: localhost

  tasks:


   - ec2_vol:

      aws_access_key: AKIA2YKZL3BBPLMX7X2F

      aws_secret_key: vXl9LJ7KRtyR05fgdSOV/GeQFsViCzM0ClwQPMiP

      instance: None

      id: vol-04503f05970b6cf25

      state: absent

      device_name: /dev/xvdb

      zone: ap-south-1b

      region: ap-south-1


De- attach volume of Ec2 via ansible

- hosts: localhost

  tasks:


   - ec2_vol:

      aws_access_key: AKIA2YKZL3BBPLMX7X2F

      aws_secret_key: vXl9LJ7KRtyR05fgdSOV/GeQFsViCzM0ClwQPMiP

      instance: None

      id: vol-04503f05970b6cf25

      device_name: /dev/xvdb

      zone: ap-south-1b

      region: ap-south-1

      delete_on_termination: yes


attach volume in ec2 via ansible

 - hosts: localhost

  tasks:


   - ec2_vol:

      aws_access_key: AKIA2YKZL3BBPLMX7X2F

      aws_secret_key: vXl9LJ7KRtyR05fgdSOV/GeQFsViCzM0ClwQPMiP

      instance: i-02fca571b802cf185

      id: vol-04503f05970b6cf25

      device_name: /dev/xvdb

      zone: ap-south-1b

      region: ap-south-1

      delete_on_termination: yes


Create volume via ansible

 - hosts: localhost

  tasks:

   - ec2_vol:

      aws_access_key: AKIA2YKZL3BBPLMX7X2F

      aws_secret_key: vXl9LJ7KRtyR05fgdSOV/GeQFsViCzM0ClwQPMiP

      volume_size: 10

      device_name: /dev/xvdb

      volume_type: io1

      iops: 100

      zone: ap-south-1b

      region: ap-south-1

      tags:

        Name: prod-vol


create EC2 Instance

 Create one Ec2- instance 



vim ec2.yml 


- hosts: localhost

  tasks:

   - ec2:

      aws_access_key: AKIA2YKZL3BBPLMX7X2F

      aws_secret_key: vXl9LJ7KRtyR05fgdSOV/GeQFsViCzM0ClwQPMiP

      key_name: ansible-key

      group: ansible-sg

      instance_type: t2.micro

      image: ami-0a23ccb2cdd9286bb

      count: 1

      instance_tags:

       Name: ec2-server

      vpc_subnet_id: subnet-38b3de74

      region: ap-south-1

      assign_public_ip: yes

ansible-playbook ec2.yml 








Wednesday, 1 September 2021

amazon.aws.ec2 – create, terminate, start or stop an instance in ec2

 

Examples

# Note: These examples do not set authentication details, see the AWS Guide for details.

# Basic provisioning example
- amazon.aws.ec2:
    key_name: mykey
    instance_type: t2.micro
    image: ami-123456
    wait: yes
    group: webserver
    count: 3
    vpc_subnet_id: subnet-29e63245
    assign_public_ip: yes

# Advanced example with tagging and CloudWatch
- amazon.aws.ec2:
    key_name: mykey
    group: databases
    instance_type: t2.micro
    image: ami-123456
    wait: yes
    wait_timeout: 500
    count: 5
    instance_tags:
       db: postgres
    monitoring: yes
    vpc_subnet_id: subnet-29e63245
    assign_public_ip: yes

# Single instance with additional IOPS volume from snapshot and volume delete on termination
- amazon.aws.ec2:
    key_name: mykey
    group: webserver
    instance_type: c3.medium
    image: ami-123456
    wait: yes
    wait_timeout: 500
    volumes:
      - device_name: /dev/sdb
        snapshot: snap-abcdef12
        volume_type: io1
        iops: 1000
        volume_size: 100
        delete_on_termination: true
    monitoring: yes
    vpc_subnet_id: subnet-29e63245
    assign_public_ip: yes

# Single instance with ssd gp2 root volume
- amazon.aws.ec2:
    key_name: mykey
    group: webserver
    instance_type: c3.medium
    image: ami-123456
    wait: yes
    wait_timeout: 500
    volumes:
      - device_name: /dev/xvda
        volume_type: gp2
        volume_size: 8
    vpc_subnet_id: subnet-29e63245
    assign_public_ip: yes
    count_tag:
      Name: dbserver
    exact_count: 1

# Multiple groups example
- amazon.aws.ec2:
    key_name: mykey
    group: ['databases', 'internal-services', 'sshable', 'and-so-forth']
    instance_type: m1.large
    image: ami-6e649707
    wait: yes
    wait_timeout: 500
    count: 5
    instance_tags:
        db: postgres
    monitoring: yes
    vpc_subnet_id: subnet-29e63245
    assign_public_ip: yes

# Multiple instances with additional volume from snapshot
- amazon.aws.ec2:
    key_name: mykey
    group: webserver
    instance_type: m1.large
    image: ami-6e649707
    wait: yes
    wait_timeout: 500
    count: 5
    volumes:
    - device_name: /dev/sdb
      snapshot: snap-abcdef12
      volume_size: 10
    monitoring: yes
    vpc_subnet_id: subnet-29e63245
    assign_public_ip: yes

# Dedicated tenancy example
- amazon.aws.ec2:
    assign_public_ip: yes
    group_id: sg-1dc53f72
    key_name: mykey
    image: ami-6e649707
    instance_type: m1.small
    tenancy: dedicated
    vpc_subnet_id: subnet-29e63245
    wait: yes

# Spot instance example
- amazon.aws.ec2:
    spot_price: 0.24
    spot_wait_timeout: 600
    keypair: mykey
    group_id: sg-1dc53f72
    instance_type: m1.small
    image: ami-6e649707
    wait: yes
    vpc_subnet_id: subnet-29e63245
    assign_public_ip: yes
    spot_launch_group: report_generators
    instance_initiated_shutdown_behavior: terminate

# Examples using pre-existing network interfaces
- amazon.aws.ec2:
    key_name: mykey
    instance_type: t2.small
    image: ami-f005ba11
    network_interface: eni-deadbeef

- amazon.aws.ec2:
    key_name: mykey
    instance_type: t2.small
    image: ami-f005ba11
    network_interfaces: ['eni-deadbeef', 'eni-5ca1ab1e']

# Launch instances, runs some tasks
# and then terminate them

- name: Create a sandbox instance
  hosts: localhost
  gather_facts: False
  vars:
    keypair: my_keypair
    instance_type: m1.small
    security_group: my_securitygroup
    image: my_ami_id
    region: us-east-1
  tasks:
    - name: Launch instance
      amazon.aws.ec2:
         key_name: "{{ keypair }}"
         group: "{{ security_group }}"
         instance_type: "{{ instance_type }}"
         image: "{{ image }}"
         wait: true
         region: "{{ region }}"
         vpc_subnet_id: subnet-29e63245
         assign_public_ip: yes
      register: ec2

    - name: Add new instance to host group
      add_host:
        hostname: "{{ item.public_ip }}"
        groupname: launched
      loop: "{{ ec2.instances }}"

    - name: Wait for SSH to come up
      delegate_to: "{{ item.public_dns_name }}"
      wait_for_connection:
        delay: 60
        timeout: 320
      loop: "{{ ec2.instances }}"

- name: Configure instance(s)
  hosts: launched
  become: True
  gather_facts: True
  roles:
    - my_awesome_role
    - my_awesome_test

- name: Terminate instances
  hosts: localhost
  tasks:
    - name: Terminate instances that were previously launched
      amazon.aws.ec2:
        state: 'absent'
        instance_ids: '{{ ec2.instance_ids }}'

# Start a few existing instances, run some tasks
# and stop the instances

- name: Start sandbox instances
  hosts: localhost
  gather_facts: false
  vars:
    instance_ids:
      - 'i-xxxxxx'
      - 'i-xxxxxx'
      - 'i-xxxxxx'
    region: us-east-1
  tasks:
    - name: Start the sandbox instances
      amazon.aws.ec2:
        instance_ids: '{{ instance_ids }}'
        region: '{{ region }}'
        state: running
        wait: True
        vpc_subnet_id: subnet-29e63245
        assign_public_ip: yes
  roles:
    - do_neat_stuff
    - do_more_neat_stuff

- name: Stop sandbox instances
  hosts: localhost
  gather_facts: false
  vars:
    instance_ids:
      - 'i-xxxxxx'
      - 'i-xxxxxx'
      - 'i-xxxxxx'
    region: us-east-1
  tasks:
    - name: Stop the sandbox instances
      amazon.aws.ec2:
        instance_ids: '{{ instance_ids }}'
        region: '{{ region }}'
        state: stopped
        wait: True
        vpc_subnet_id: subnet-29e63245
        assign_public_ip: yes

#
# Start stopped instances specified by tag
#
- amazon.aws.ec2:
    instance_tags:
        Name: ExtraPower
    state: running

#
# Restart instances specified by tag
#
- amazon.aws.ec2:
    instance_tags:
        Name: ExtraPower
    state: restarted

#
# Enforce that 5 instances with a tag "foo" are running
# (Highly recommended!)
#

- amazon.aws.ec2:
    key_name: mykey
    instance_type: c1.medium
    image: ami-40603AD1
    wait: yes
    group: webserver
    instance_tags:
        foo: bar
    exact_count: 5
    count_tag: foo
    vpc_subnet_id: subnet-29e63245
    assign_public_ip: yes

#
# Enforce that 5 running instances named "database" with a "dbtype" of "postgres"
#

- amazon.aws.ec2:
    key_name: mykey
    instance_type: c1.medium
    image: ami-40603AD1
    wait: yes
    group: webserver
    instance_tags:
        Name: database
        dbtype: postgres
    exact_count: 5
    count_tag:
        Name: database
        dbtype: postgres
    vpc_subnet_id: subnet-29e63245
    assign_public_ip: yes

#
# count_tag complex argument examples
#

    # instances with tag foo
- amazon.aws.ec2:
    count_tag:
        foo:

    # instances with tag foo=bar
- amazon.aws.ec2:
    count_tag:
        foo: bar

    # instances with tags foo=bar & baz
- amazon.aws.ec2:
    count_tag:
        foo: bar
        baz:

    # instances with tags foo & bar & baz=bang
- amazon.aws.ec2:
    count_tag:
        - foo
        - bar
        - baz: bang