Ansible Installation, Playbooks for Setting Up Website in Remote Machine
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 On Ubuntu
sudo apt update
sudo apt install software-properties-common -y
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible -y
ansible --version
Installing Ansible On CentOS
sudo yum install epel-release -y
sudo yum install ansible -y
ansible --version
SCP Commands
Copy files From Local machine to Remote machine
scp -i <private-key-file-path> <files to copy> <user>@<IP>:<Remote-machine-path>
Example:
scp -i Downloads/control.pem sample.txt ubuntu@54.165.128.104:/home/ubuntu/
Sample Inventory File
##Host Levelwebserver01 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
Host level has the highest priority, If you mention anything like username or Keyfile etc. It will take only, which are mentioned at the host level.
Ansible Commands
To test the connection of a particular Remote Machine
ansible -i <Inventoryfile path> -m ping <hostname>
To test the connection of a 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
Copy files to the Remote machine name starting with the web
ansible -i <Inventoryfile path> -m copy -a "src=index.html dest=/var/www/html/index.html" 'web*' --become
Installing httpd in centos Remote machine
ansible -i <Inventoryfile path> -m yum -a "name=httpd state=present" websrvgrp --become
Start & Enable httpd in centos Remote machine
ansible -i <Inventoryfile path> -m service -a "name=httpd state=started enabled=yes" websrvgrp --become
Playbooks
!!! 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 <Inventory file path> sample.yml
Writing Playbook For Installing Httpd service in remote machines with start and enable and copying index.html files from the local machine to the remote machine.
- name: Install httpd and start 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 conditions
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 need to be installed
apt install python3-pippip install botopip install boto3pip install botocore
Creating Files to store Variables
vim vpc_setup.txt
Variables
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
Playbook
- hosts: localhost
connection: local
gather_facts: False
tasks:
- name: Import vpc variables
include_vars: /path/vpc_setup - name: create 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 a 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 a 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 a 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 a 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 a 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 a 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 a new nat gateway and allocate a 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
apt install python3-pippip install botopip install boto3pip install botocore
Playbook
- 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 private key 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
Ansible Configuration File
Note - You should save the configuration file with the name ansible.cfg
vim ansible.cfg
Sample Ansible Configuration File
[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
Subscribe to my newsletter
Read articles from Charan kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Charan kumar
Charan kumar
Devops engineer at Acro Computing India. Skilled in Git, Ansible, Jenkins, Docker, Kubernetes.