Skip to content

Ansible

Ansible is an open source IT Configuration Management, Deployment & Orchestration tool. It aims to provide large productivity gains to a wide variety of automation challenges. This tool is very simple to use yet powerful enough to automate complex multi-tier IT application environments.

Installing Ansible

Sample Inventory file

##Host Level

webserver01    ansible_host=<Private IP>
webserver02    ansible_host=<Private IP>
webserver03    ansible_host=<Private IP>      
dbserver01     ansible_host=<Private IP>
dbserver02     ansible_host=<Private IP>      ansible_user=ubuntu

##Group Level

[Group1]
webserverserver01
webserverserver02
webserverserver03

[Group2]
dbserver01
dbserver02

##Parent Level

[dc_mumbai:children] 
webservergrp
dbsrvgrp

##Variables

[dc_mumbai:vars]
ansible_user=<user>
ansible_ssh_private_key_file=<key-path>
Info-note

Host level has the Highest priority , If you mention anything like username or Keyfile etc. It will take only which are mentioned in the host level.

Ansible Commands¶

To test the connection of particular Remote Machine

    ansible -i <Inventoryfile path> -m ping <hostname>

To test the connection of particular Group of Remote Machines

    ansible -i <Inventoryfile path> -m ping <Groupname>

To test the connection of All Remote Machine

    ansible -i <Inventoryfile path> -m ping all

To see details about the machine

    ansible -i <Inventoryfile path> -m setup <hostname>

Some Example Ad hoc Commands¶

Ad hoc Commands Copy files to Remote machines name starts with web

ansible -i -m copy -a "src=index,html dest=/var/www/html/index.html" 'web*' --become Installing httpd in centos Remote machine

ansible -i -m yum -a "name=httpd state=present" websrvgrp --become Start & Enable httpd in centos Remote machine

ansible -i -m service -a "name=httpd state=started enabled=yes" websrvgrp --become Info

Ansible Playbooks should be with .yml or .yaml Extension for example vim sample.yml

Playbook For Creating Files & Directories¶

- name: Creating Files & Directories
  hosts: <host>
  become: yes
  tasks:
    - name: Creating a Directory
        file:
        path: /tmp/welcome
        state: directory

    - name: Creating a File
        file:
        path: /tmp/sample.txt
        state: touch

To Execute the playbook

ansible-playbook -i sample.yml

Writing Playbook For Installing Httpd service in remote machines with start and enable and copying index.html files from local machine to remote machine¶

    - name: Install httpd and starting the service
      hosts: all
      tasks:
        - name: Installing the Apache package
        yum:
            name: httpd
            state: present


        - name: Starting service
        service:
            name: httpd
            state: started
            enabled: yes

        - name: Copy file with owner and permissions
        copy:
            src: ./index.html
            dest: /var/www/html/index.html

        - name: Restarting service
        service:
            name: httpd
            state: restarted

Writing Playbook for Setting Up Website in Remote Machine¶

    - name: Setting up Website
      hosts: websrv
      gather_facts: False
      become: True

      tasks:
        - name: Installing Packages in CentOS
        yum:
            name: "{{item}}"
            state: present
        when: ansible_distribution == "CentOS"
        loop:
            - httpd
            - wget
            - unzip

        - name: Start & Enable httpd
        service:
            name: httpd
            state: started
            enabled: yes

        - name: Downloading Source code
        get_url:
            url: https://www.tooplate.com/zip-templates/2114_pixie.zip
            dest: /opt

        - name: Unarchive a file that is already on the remote machine
        unarchive:
            src: /opt/2114_pixie.zip
            dest: /opt
            remote_src: yes

        - name : Deploy Website
        copy:
            src: /opt/2114_pixie/
            dest: /var/www/html/
            remote_src: yes


        - name: Restarting httpd service
        service:
            name: httpd
            state: restarted

Writing Playbook for Setting Up Website in Remote Machine with Conditions & Handlers.¶

    - name: Writing playbook for loops and condtions
      hosts: all
      tasks:
        - name: Install packages on centos
        yum:
            name: "{{item}}"
            state: present
        when: ansible_distribution == "CentOS"
        loop:
            - httpd
            - wget
            - unzip
            - zip
            - git

        - name: Install packages on ubuntu 
        apt:
            name: "{{item}}"
            state: present
            update_cache: yes
        when: ansible_distribution == "Ubuntu"
        loop:
            - apache2
            - wget
            - unzip
            - zip
            - git


        - name: Start & enable service on CentOS
        service:
        name: httpd
        state: started
        enabled: yes
        when: ansible_distribution == "CentOS"

        - name: Start & enable service on Ubuntu
        service:
        name: apache2
        state: started
        enabled: yes
        when: ansible_distribution == "Ubuntu"


        - name: Push index.html on centos
        copy:
            src: index.html
            dest: /var/www/html/
            backup: yes
        when: ansible_distribution == "CentOS"
        notify:
            - Restart service on CentOS

        - name: Push index.html on ubuntu
        copy:
            src: index.html
            dest: /var/www/html/
            backup: yes
        when: ansible_distribution == "Ubuntu"
        notify:
            - Restart service on Ubuntu

    handlers:
        - name: Restart service on CentOS
        service:
            name: httpd
            state: restarted
            enabled: yes
        when: ansible_distribution == "CentOS"

        - name: Restart service on Ubuntu
        service:
            name: apache2
            state: restarted
            enabled: yes
        when: ansible_distribution == "Ubuntu"

Writing Playbook to Create VPC in AWS Cloud and Including Variables from different File¶

Requirements python >= 3.6

boto3 >= 1.15.0

botocore >= 1.18.0

apt install python3-pip

pip install boto

pip install boto3

pip install botocore

Creating File to store Variables

vim vpc_setup.txt

    vpc_name: "Vprofile-vpc"

    #Vpc-range
    vpcrange: '172.21.0.0/16'

    #subnet range
    pubip1: '172.21.1.0/24'
    pubip2: '172.21.2.0/24'
    pubip3: '172.21.3.0/24'
    pvtip1: '172.21.4.0/24'
    pvtip2: '172.21.5.0/24'
    pvtip3: '172.21.6.0/24'

    #region
    region: 'us-east-2'

    #zone names
    zone1: us-east-2a
    zone2: us-east-2b
    zone3: us-east-2c


    state: present
- hosts: localhost
  connection: local
  gather_facts: False
  tasks:
    - name: Import vpc variables
    include_vars: /path/vpc_setup

    - name: create Vprofile vpc
    ec2_vpc_net:
        name: "{{vpc_name}}"
        cidr_block: "{{vpcrange}}"
        region: "{{region}}"
        dns_support: yes
        dns_hostnames: yes
        tenancy: default
        state: "{{state}}"
    register: vpcout

    - name: Create public subnet for zone1
    ec2_vpc_subnet:
        vpc_id: "{{vpcout.vpc.id}}"
        region: "{{region}}"
        az: "{{zone1}}"
        state: "{{state}}"
        cidr: "{{pubip1}}"
        map_public: yes
        tags:
            Name: vprofile_pubsub1
    register: pubsub1_out

    - name: Create public subnet for zone2
    ec2_vpc_subnet:
        vpc_id: "{{vpcout.vpc.id}}"
        region: "{{region}}"
        az: "{{zone2}}"
        state: "{{state}}"
        cidr: "{{pubip2}}"
        map_public: yes
        tags:
        Name: vprofile_pubsub2
    register: pubsub2_out

    - name: Create public subnet for zone3
    ec2_vpc_subnet:
        vpc_id: "{{vpcout.vpc.id}}"
        region: "{{region}}"
        az: "{{zone3}}"
        state: "{{state}}"
        cidr: "{{pubip3}}"
        map_public: yes
        tags:
        Name: vprofile_pubsub3
    register: pubsub3_out

    - name: Create private subnet for zone1
    ec2_vpc_subnet:
        vpc_id: "{{vpcout.vpc.id}}"
        region: "{{region}}"
        az: "{{zone1}}"
        state: "{{state}}"
        cidr: "{{pvtip1}}"
        map_public: yes
        tags:
        Name: vprofile_pvtsub1
    register: pvtsub1_out

    - name: Create private subnet for zone2
    ec2_vpc_subnet:
        vpc_id: "{{vpcout.vpc.id}}"
        region: "{{region}}"
        az: "{{zone2}}"
        state: "{{state}}"
        cidr: "{{pvtip2}}"
        map_public: yes
        tags:
        Name: vprofile_pvtsub2
    register: pvtsub2_out

    - name: Create private subnet for zone3
    ec2_vpc_subnet:
        vpc_id: "{{vpcout.vpc.id}}"
        region: "{{region}}"
        az: "{{zone3}}"
        state: "{{state}}"
        cidr: "{{pvtip3}}"
        map_public: yes
        tags:
        Name: vprofile_pvtsub3
    register: pvtsub3_out

    - name: Internet gateway setup
    ec2_vpc_igw:
        vpc_id: "{{vpcout.vpc.id}}"
        region: "{{region}}"
        state: "{{state}}"
        tags:
        Name: vprofile_IGW
    register: igw_out

    - name: public subnet route table
    ec2_vpc_route_table:
        vpc_id: "{{vpcout.vpc.id}}"
        region: "{{region}}"
        tags:
        Name: vprofile_Public
        subnets:
        - "{{pubsub1_out.subnet.id}}"
        - "{{pubsub2_out.subnet.id}}"
        - "{{pubsub3_out.subnet.id}}"
        routes:
        - dest: 0.0.0.0/0
            gateway_id: "{{ igw_out.gateway_id }}"
    register: public_route_table

    - name: Create new nat gateway and allocate new EIP if a nat gateway does not yet exist in the subnet.
    ec2_vpc_nat_gateway:
        state: "{{state}}"
        subnet_id: "{{pubsub1_out.subnet.id}}"
        wait: true
        region: "{{region}}"
        if_exist_do_not_create: true
    register: nat_out

    - name: private subnet route table
    ec2_vpc_route_table:
        vpc_id: "{{vpcout.vpc.id}}"
        region: "{{region}}"
        tags:
        Name: vprofile_Private
        subnets:
        - "{{pvtsub1_out.subnet.id}}"
        - "{{pvtsub2_out.subnet.id}}"
        - "{{pvtsub3_out.subnet.id}}"
        routes:
        - dest: 0.0.0.0/0
            gateway_id: "{{nat_out.nat_gateway_id}}"
    register: private_route_table

    - debug:
        var: "{{item}}"
    loop:
        - vpcout.vpc.id
        - pubsub1_out.subnet.id
        - pubsub2_out.subnet.id
        - pubsub3_out.subnet.id
        - pvtsub1_out.subnet.id
        - pvtsub2_out.subnet.id
        - pvtsub3_out.subnet.id
        - igw_out.gateway_id
        - public_route_table.route_table.id
        - nat_out.nat_gateway_id
        - private_route_table.route_table.id

    - set_fact:
        vpcid: "{{vpcout.vpc.id}}"
        pubsublid: "{{ pubsub1_out.subnet.id }}"
        pubsub2id: "{{ pubsub2_out.subnet.id }}"
        pubsub3id: "{{ pubsub3_out.subnet.id }}"
        privsublid: "{{ pvtsub1_out.subnet.id }}"
        privsub2id: "{{ pvtsub2_out.subnet.id }}"
        privsub3id: "{{ pvtsub3_out.subnet.id }}"
        igwid: "{{ igw_out.gateway_id }}"
        pubRTid: "{{ public_route_table.route_table.id }}"
        NATGWid: "{{ nat_out.nat_gateway_id }}"
        privRTid: "{{ private_route_table.route_table.id }}"
        cacheable: yes

    - name: creating file for vpc output
    copy:
        content: "vpcid: {{vpcout.vpc.id}}\n pubsublid: {{ pubsub1_out.subnet.id }}\npubsub2id: {{ pubsub2_out.subnet.id }}\npubsub3id: {{ pubsub3_out.subnet.id }}\nprivsublid: {{ pvtsub1_out.subnet.id }}\nprivsub2id: {{ pvtsub2_out.subnet.id }}\nprivsub3id: {{ pvtsub3_out.subnet.id }}\nigwid: {{ igw_out.gateway_id }}\npubRTid: {{ public_route_table.route_table.id }}\nNATGWid: {{ nat_out.nat_gateway_id }}\nprivRTid: {{ private_route_table.route_table.id }}"
        dest: /home/ubuntu/Vprofile/vars/output_vars

Launching Ec2 Instance in AWS Cloud¶

Requirements
python >= 3.6

boto3 >= 1.15.0

botocore >= 1.18.0

apt install python3-pip

pip install boto

pip install boto3

pip install botocore

- name: Launching Ec2 Instance

hosts: localhost connection: local tasks: - name: Creating Key pair amazon.aws.ec2_key: name: samplekey region: us-west-1 register: key

 - debug:
    var: key

 - name: Storing privatekey into a file
   copy:
      content: "{{key.key.private_key}}"
      dest: "./sample.pem"
      mode: 0600
   when: key.changed


 - name: Creating Security Group
   amazon.aws.ec2_group:
     name: mysg
     description: Allowing 22 and 80
     vpc_id: vpc-0c8e70cf05b1342ac
     region: us-west-1
     rules:
       - proto: tcp
         from_port: 22
         to_port: 22
         cidr_ip: 0.0.0.0/0
         rule_desc: allow all on port 80 & 22
   register: sg_out

 - name: Launching bastion_host
   ec2:
      key_name: "samplekey"
      region: us-west-1
      instance_type: t2.micro
      image: ami-0573b70afecda915d
      wait: yes
      wait_timeout: 300
      instance_tags:
        name: "Ansible Instance"
        project: vprofile
        owner: devops team
      exact_count: 1
      count_tag:
        name: "Ansible Instance"
        project: vprofile
        owner: devops team
      group_id: "{{sg_out.group_id}}"
      vpc_subnet_id: subnet-0c4734c845e549cda
   register: instance
Note

You should save the configuration file with name ansible.cfg

vim ansible.cfg
[defaults]
host_key_checking=False
inventory=<Inventory File Path>
timeout=20
log_path=/var/log/ansible_world.log
remote_port=22
remote_user=<username>

[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False