Ansible: Automating Apache Web Server Configuration over AWS with Dynamic Inventory

Ansible: Automating Apache Web Server Configuration over AWS with Dynamic Inventory

Today we're going to launch an EC2 instance running on RHEL8 over AWS Cloud and configure Apache Web Server on top of it. The interesting part is that we're going to automate this entire process with the help of Ansible. And this time we'll be using the concept of dynamic inventory. For this you require an AWS account, you may go with the free tier account provided by AWS, as it has all we need.

What's a dynamic inventory?

A dynamic inventory is a script which when called upon, goes to a specified infrastructure (in this case, AWS EC2) over the network, fetches the public IP of all active instances and updates them in the host list. It comes very handy while working with AWS EC2 instances whose IP changes every time it's stopped and restarted.

Since now you know something about dynamic inventory, so let's get started:

Step 1: Updating Ansible's configuration file

No alt text provided for this image

We'll have to update the configuration file of Ansible present at /etc/ansible/ansible.conf directory. This includes providing the path of you inventory and the private key file (for authentication), a few other parameters and providing privilege escalation.

[defaults]
inventory = /etc/myverse/myinventory
host_key_checking = False
private_key_file = /etc/myverse/myroles/awsec2setup/files/mykey951753.pem
remote_user = ec2-user
ask_pass = False
become = TRUE

[privilege_escalation]
become = TRUE
become_user = root
become_method = sudo
become_ask_pass = FALSE


Step 2: Downloading the scripts and updating them

For configuring dynamic inventory we'll have to download two per-created scripts (i.e. ec2.py and ec2.ini). The GitHub repository link is provided below:

https://github.com/ansible/ansible/tree/stable-2.9/contrib/inventory

No alt text provided for this image

To download the files directly on your local system use the following commands:

cmd# wget https://raw.githubusercontent.com/ansible/ansible/stable-2.9/contrib/inventory/ec2.ini

cmd# wget https://raw.githubusercontent.com/ansible/ansible/stable-2.9/contrib/inventory/ec2.py

Note: Download/Save the files in the same directory that you provided in the Ansible's configuration file as inventory.

Since we're using a Linux based OS so we'll have to modify the shebang in ec2.py file as follows:

No alt text provided for this image

To make this script an executable use the following command:

cmd# chmod +x ec2.py

Now, the name of the file will be displayed in green (which represents an executable),

No alt text provided for this image

Also do the same for ec2.ini file.

Now, whenever Ansible will come to this directory as directed by it's configuration file and find this executable script it'll automatically run it. And the ec2.py will go to the specified AWS account through the help of boto module and fetch the public IPs of all active instances.

Note: If you don't have the boto module installed then use the following command:

cmd# pip3 install boto

To initialize use the following commands:

cmd# export AWS_REGION='ap-south-1'

cmd# export AWS_ACCESS_KEY_ID=your_AWS_Access_Key_ID

cmd# export AWS_SECRET_ACCESS_KEY=your_AWS_Secret_Key

Now, you can run the following command to list all host's IPs:

cmd# ansible all --list-hosts

No alt text provided for this image

Note: It takes some time so don't panic, just sit back and relax.

In my case, currently there are zero active instances so no host IP is being displayed.


Step 3: Launching AWS EC2 instance

Before we write the playbook we need to collect some information as per our EC2 instance requirements. This can either be done through the CLI or from the WebUI's EC2 console management window. I'm going with the WebUI.

region

No alt text provided for this image


image

No alt text provided for this image


instance_type

No alt text provided for this image


count and vpc_subnet_id

No alt text provided for this image


group_id

No alt text provided for this image


key_name

No alt text provided for this image

  

aws_access_key and aws_secret_key

No alt text provided for this image

Note: You get the Secret access key only once i.e. when you create the user in IAM services.

Once we have all that information we can start writing our playbook,

- hosts: localhost
  vars_files:
    - securevault.yml
  tasks:
    - name: Provisioning OS in AWS cloud
      ec2:
        region: "ap-south-1"
        image: "ami-052c08d70def0ac62"
        instance_type: "t2.micro"
        count: 1
        vpc_subnet_id: "subnet-8b2b27e3"
        group_id: "sg-0636cf1d8d7737ecf"
        instance_tags:
          Name: task2
        key_name: "mykey951753"
        assign_public_ip: yes
        state: present
        wait: yes
        aws_access_key: "{{ acc_key_id }}"
        aws_secret_key: "{{ sec_acc_key }}"
      register: log

    - debug:
        var: log

It's always a good idea to save the sensitive data on another file and hash it instead of storing it in plane text format. And for that Ansible provides a service called vault which is capable of hashing and locking the files securely. As you can see, I've used two variables (i.e. acc_key_id and sec_acc_key) which is stored in another file named securevault.yml present in the same directory. The securevault.yml file contains the value of both the variables and as it's name suggests, it's been hashed and locked using Ansible-vault.

No alt text provided for this image

To create a file with vault and to associate with unique id use:

cmd# ansible-vault create --vault-id ankit@prompt abc.yml

To hash and lock a pre-created file using Ansible-vault use the following command:

cmd# ansible-vault encrypt secure.yml

It'll prompt for a password, provide that, confirm it and lock the file.

To edit a file locked with Ansible-vault use the following command:

cmd# ansible-vault edit secure.yml

It'll prompt for the password, provide that to edit the file. Once you exit the file it'll automatically get locked again.

Remember, one can only access, read, or modify the contents of this file if he/she has the password.

Now, let's run the playbook:

cmd# ansible-playbook --vault-id ankit@prompt awsec2.yml

It'll prompt for the vault password, provide it and wait for some time.

No alt text provided for this image
No alt text provided for this image
No alt text provided for this image

You can also view it in the EC2 management console on WebUI.

No alt text provided for this image

Now if you use the following command it'll fetch the IP of this instance dynamically:

cmd# ansible all --list-hosts

To ensure that you are properly use the ping module:

cmd# ansible all -m ping

No alt text provided for this image


Step 4: Configuring Apache Web Server

The playbook for configuring Apache Web Server or httpd goes something like this:

- name: Configuring Apache Webserver
  hosts: all
  tasks:
    - name: Installing httpd software
      package:
        name: "httpd"
        state: present
      when: ansible_distribution == "RedHat"

    - name: Copying webpages
      copy:
        src: "/etc/myverse/mydata/html_files/"
        dest: "/var/www/html/"
        mode: preserve

    - name: Enabling web server
      service:
        name: "httpd"
        state: started
        enabled: yes


Here, I'm copying the contents from the local directory /etc/myverse/mydata/html_files/ into the directory /var/www/html/ present on the instance. The html_files directory contains a demo webpage named home.html that we'll be hosting on the web server.

No alt text provided for this image

Note: Only the webpages present in /var/www/html/ directory will be hosted.

Now, let's run the playbook,

cmd# ansible-playbook httpdaws.yml

No alt text provided for this image

Finally, the web server has been configured over the EC2 instance. You can visit the webpage home.html and see it's content using the public IP of the instance.

No alt text provided for this image

You can merge both the playbooks so that you have to run the command only once.

- name: Launching EC2 instance on AWS
  hosts: localhost
  vars_files:
    - securevault.yml
  tasks:
    - name: Provisioning OS in AWS cloud
      ec2:
        region: "ap-south-1"
        image: "ami-052c08d70def0ac62"
        instance_type: "t2.micro"
        count: 1
        vpc_subnet_id: "subnet-8b2b27e3"
        group_id: "sg-0636cf1d8d7737ecf"
        instance_tags:
          name: task2
        key_name: "mykey951753"
        assign_public_ip: yes
        state: present
        wait: yes
        aws_access_key: "{{ acc_key_id }}"
        aws_secret_key: "{{ sec_acc_key }}"
      register: log

    - debug:
        var: log

- name: Configuring Apache Webserver
  hosts: all
  tasks:
    - name: Installing httpd software
      package:
        name: "httpd"
        state: present
      when: ansible_distribution == "RedHat"

    - name: Copying webpages
      copy:
        src: "/etc/myverse/mydata/html_files/"
        dest: "/var/www/html/"
        mode: preserve

    - name: Enabling web server
      service:
        name: "httpd"
        state: started
        enabled: yes





Thanks...

Hope you liked it...

See you again...!!!

要查看或添加评论,请登录

Ankit Kumar的更多文章

社区洞察

其他会员也浏览了