This is an Ansible Playbook to deploy your website from GitHub to both staging and production environments in AWS.
- Fully Automated Playbook
- You can deploy your code to any number of EC2 instances in a single run
- This Playbook will deploy the code from GitHub to each servers in selected project environment in one-by-one manner.
- The selection of servers is based on AWS tags. To implement this Playbook in an AWS infrastructure, each server in that infra should have below two tags:
- project :Indicating the project in which this instance belongs to.
- Example: project: uber, project:ola
- env :Indicating the environment of the project.
- Example: env:prod, env:stg
- project :Indicating the project in which this instance belongs to.
- You will be prompted to Enter below details:
-
Datacenter access details such as
- Access Key for AWS access
- Secret Key for AWS access
- AWS Region
-
Project details such as
- Project name
- Project Environment(stg/prod)
-
Server access details such as
- SSH user of servers
- SSH port of servers
- SSH key name
-
Git URL in which your your project is uploaded.
-
- Install Ansible in Ansible Master server. Click here for Ansible Installation steps.
This task will connects to the AWS with provided access key and secret key and fetch the details of all the servers which are satisfying below conditions and store them to a variable server_info
- Region is the provided region
- 'env' tag of server is the environment provided by you
- 'project' tag of the server is the project provided by you
- name: "Fetch details Servers"
ec2_instance_info:
aws_access_key: "{{accesskey}}"
aws_secret_key: "{{secretkey}}"
region: "{{region}}"
filters:
"tag:env": "{{env}}"
"tag:project": "{{project}}"
register: server_info
This task will create an in-memory inventory file with the details fetched from above task and ssh user, ssh port and ssh key name provided by you
- name: "Create in-memory inventory"
add_host:
groups: "server"
hostname: "{{ item.public_ip_address }}"
ansible_host: "{{ item.public_ip_address }}"
ansible_user: "{{ssh_user}}"
ansible_port: "{{ssh_port}}"
ansible_private_key_file: "{{key_name}}.pem"
ansible_ssh_common_args: "-o StrictHostKeyChecking=no"
with_items:
- "{{server_info.instances}}"
This task will clone the code from the Github URL provided by you and copy it to a directory in the server(here, I set that to /var/www/website/ in variables.vars)
- name: "clone repository from Github"
git:
repo: "{{git_url}}"
dest: "{{clone_dir}}"
register: git_info
This task will stop HTTPD service in the server and wait 10 seconds to off-load that instance from the Loadbalancer This task will run only if there is a change between the code in Github and code in the server
- If you want, you can modify connection draning time as per the properties of your project/Loadbalancer from variables.vars
- name: "off-load instance from loadbalancer"
when: git_info.changed == true
service:
name: httpd
state: stopped
- name: "wait for connection draining"
when: git_info.changed == true
pause:
seconds: "{{offload_wait}}"
These set of tasks will perform the below taks only if there is a change between the code in Github and code in the server.
- Copy contents from /var/www/websites/ to document root(it is now set to /var/www/html in variables.vars)
- Set owner and group of files properly under docuement root
- Start HTTPD service
- Wait for 20 seconds to load that server back to the Loadbalancer. You can change this wait time as per your project requirements in variables.vars
- name: "copy contents to document root"
when: git_info.changed == true
copy:
src: "{{clone_dir}}"
dest: "{{doc_root}}"
owner: "{{owner}}"
group: "{{group}}"
remote_src: true
- name: "Load instance back to loadbalancer"
when: git_info.changed == true
service:
name: httpd
state: restarted
enabled: true
- name: "wait for health check pass"
when: git_info.changed == true
pause:
seconds: {{"onload_wait"}}
These tasks are to print the outcome of the deployment process in the screen.
- name: "deployment status"
when: git_info.changed == false
debug:
msg: " {{ansible_hostname}} {{ansible_host}} already have the latest version"
- name: "deployment status 2"
when: git_info.changed == true
debug:
msg: " {{ansible_hostname}} {{ansible_host}} DEPLOYMENT SUCCESSFULL"
-
Put the Playbook and variables.vars in the Ansible Master server working directory.
-
Run a syntax check
ansible-playbook main.yml --syntax-check
- Execute the Playbook
ansible-playbook main.yml
x------------------x---------------------x---------------------x-------------------x--------------------x---------------------x-------------------x