Configuring Webserver in AWS EC2 using Ansible

Base Plan

What we are going to do:

  • Provision EC2 instance through ansible
  • Retrieving facts like IP of EC2 instance
  • Building inventory using dynamic inventory
  • Configuring webserver in EC2 instance using ansible
  • Deploying a webpage in the webserver

To make ansible connect with aws we require a python library named boto or boto3 so make sure your linux control node (ansible) have that.

pip3 install boto boto3 -y

Next step, we require dynamic inventory so we need to grab 2 files which are ec2.py and ec2.ini.

https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.py

https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.ini

We need to provide our access key id and secret key id in our ec2.ini and we also need to export them.

$ export AWS_ACCESS_KEY_ID='YOUR_AWS_API_KEY'
$ export AWS_SECRET_ACCESS_KEY='YOUR_AWS_API_SECRET_KEY'

For more detailed explanation and process on dynamic inventory check : Getting Started with Ansible and Dynamic Amazon EC2 Inventory Management | AWS Partner Network (APN) Blog

The dynamic inventory should be empty first. My ansible.cfg looks like this:

[defaults]
#inventory = /etc/ansible/inventory
inventory = /root/ansible_tasks/task2/inventory2
host_key_checking = false
remote_user = ec2-user
become = true
ask_pass = false

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_password = false
AWS user for ansible

We need to create a IAM user with appropriate permission/power for ansible to launch and create resources on aws.

I am going to use vault to encrypt by aws access and secret key.

ansible-vault create --vault-id aws@prompt key.yml
access_key: your access key
secret_key: your secret key

We now need to create two roles, one for ec2 instance launch and one for deploying webserver on that.

EC2 role

tasks/main.yml

# tasks file for webserver_aws

  - name: include access/secret key aws
    include_vars: /root/ansible_tasks/task2/key.yml

  - name: creating key pair
    amazon.aws.ec2_key:
      name: "{{ key_pair_name }}"
      aws_access_key: "{{ access_key }}"
      aws_secret_key: "{{ secret_key }}"
      region: "{{ region }}"
    register: keypair

  - debug:
      var: keypair

  - copy:
      content: '{{ keypair["key"]["private_key"] }}'
      dest: /root/ansible_tasks/task2/{{ key_pair_name }}.pem
    ignore_errors: yes

  - name: create security group for our instance
    amazon.aws.ec2_group:
      name: "{{ sg_name }}"
      description: "sg having 22 and 80 ingress"
      vpc_id: "{{ vpc_id }}"
      region: "{{ region }}"
      aws_secret_key: "{{ access_key }}"
      aws_access_key: "{{ secret_key }}"
      state: present
      rules:
        - proto: tcp
          from_port: 80
          to_port: 80
          cidr_ip: 0.0.0.0/0
        - proto: tcp
          from_port: 22
          to_port: 22
          cidr_ip: 0.0.0.0/0


  - name: lauching an ec2 instance
    ec2_instance:
      region: "{{ region }}"
      aws_access_key: "{{ access_key }}"
      aws_secret_key: "{{ secret_key }}"
      instance_type: "{{ instance_type }}"
      key_name: "{{ key_pair_name }}"
      state: present
      image_id: "{{ image_id }}"
      vpc_subnet_id: "{{ subnet_id }}"
      group: "{{ sg_name }}"
      name: "{{ instance_name }}"
      assign_public_ip: yes

vars.main.yml

# vars file for webserver_aws
region: ap-south-1
instance_type: t2.micro
image_id: ami-0a9d27a9f4f5c0efc
key_pair_name: ansiblekeypair
instance_name: webserver
vpc_id: vpc-a2809dca
sg_name: sg_ansible
subnet_id: subnet-9edee4f6

Webserver role

tasks/main.yml

# tasks file for ec2_webserver

- name: include access/secret key aws
  include_vars: /root/ansible_tasks/task2/key.yml

- name: retrive facts
  ec2_instance_info:
    aws_access_key: "{{ access_key }}"
    aws_secret_key: "{{ secret_key }}"
    region: "{{ region }}"
  register: instfacts

- debug:
    var: instfacts

- name: install httpd
  package:
    name: "httpd"
    state: present
  when: ansible_os_family == "RedHat"
  register: httpd_status

- name: start httpd service
  service:
    name: "httpd"
    state: started

- name: copy webpage to root
  copy:
    src: "{{ src }}"
    dest: "{{ dest }}"
    mode: 0666
    when: httpd_status.rc == 0
    notify: restart httpd

handlers/main.yml

# handlers file for ec2_webserver
- name: restart httpd
  service:
    name: httpd
    state: restarted

vars/main.yml

# vars file for ec2_webserver
region: ap-south-1
src: /root/ansible_tasks/task2/ec2_webserver/files/index.html
dest: /var/www/html/index.html
Final Run

Run both the roles:

main-ec2.yml

- hosts: localhost
  roles:
  - role: "ec2_conf"

main-webserver.yml

- hosts: all
  roles:
  - role: "ec2_webserver"
ansible-playbook --vault-id aws@prompt main-ec2.yml
ansible-playbook --vault-id aws@prompt main-webserver.yml

Results

We successfully launched instance and configured webserver in it using ansible.

Thank you for coming this far!

Leave a comment

Design a site like this with WordPress.com
Get started