How to provision AWS infrastructure with Ansible
Infrastructure as Code (IaC) is a method to provision and manage infrastructure and other resources using declarative definition files or code. Instead of manually configuring the servers (physical or virtual) and network devices (and other resources), you can use IaC to manage the entire infrastructure lifecycle. Ansible is one of the best IaC tools, and this article explains how to use it to provision infrastructure and other resources in a public cloud.
Current vs. future modes of operation
In the current method, you manually do every task to create and build your infrastructure. You collect the cluster or region details to deploy your servers, network subnets, storage, and other items. Once you have the details, you create the virtual private cloud (VPC) project, security groups, network policies, and other items. Then you create servers (virtual machines, instances, droplets—whatever you call it) and configure them with additional disks as needed. Before you finish, you install and configure applications and packages, create users and groups, and do many other things.
In the future mode of operation, using Ansible as an IaC tool enables you to automate all those operations, and managing your infrastructure becomes more efficient. Instead of doing tasks manually, you create the resources using Ansible modules.
Why Ansible for public cloud management?
The Ansible community is rapidly growing, and product vendors are contributing more and more Ansible content to the public community. This means you have ready-to-use modules and plugins available to manage the most well-known public cloud and private cloud platforms such as AWS, Azure, Google Cloud Platform, IBM, OpenShift, OpenStack, Oracle, VMware, and others.
I'll use AWS as the example in this article. You can find documentation on all cloud modules, and the cloud modules the vendors manage are available as Ansible Content Collections in Ansible Galaxy.
How to manage AWS with Ansible
There are plenty of modules available from the community for managing AWS using Ansible. You can access the Community AWS Collection or Amazon AWS Collection from Ansible Galaxy.
[ Find out what's new in Red Hat Ansible Automation Platform 2. ]
Create Elastic Compute Cloud (EC2) instances
Creating EC2 instances in AWS is a single task using the ec2_instance module
module, but as a best practice, you can add more pretasks and validations as needed [editor's note: this article was updated on Nov. 11, 2021, to use the ec2_instance module rather than the deprecated ec2 module]:
- name: Launching EC2 instances
community.aws.ec2_instance:
#aws_access_key: "{{ec2_access_key}}"
#aws_secret_key: "{{ec2_secret_key}}"
profile: "{{ aws_boto_profile }}"
key_name: "{{ aws_demo_key }}"
security_group: "{{ aws_security_group }}"
instance_type: "{{ item.value.instance_type }}"
image_id: "{{ aws_ami_id }}"
state: present
wait: yes
wait_timeout: 300
region: "{{ aws_region }}"
tags:
Name: "{{ item.value.name }}"
detailed_monitoring: no
vpc_subnet_id: "{{ vpc_subnet_list | random }}"
network:
assign_public_ip: yes
loop: "{{ lookup('dict', ec2_new_list, wantlist=True) }}"
Create security groups
AWS security groups control the instance and other resource access. You can fine-tune the network access by source IP, network, port, and more:
- name: Create Security group
amazon.aws.ec2_group:
profile: "{{ aws_boto_profile }}"
name: "{{ aws_security_group }}"
description: 'Security Group with SSH and HTTP rules'
vpc_id: "{{ aws_vpc_id }}"
region: "{{ aws_region }}"
rules:
- proto: tcp
ports:
- 80
cidr_ip: 0.0.0.0/0
rule_desc: allow all on port 80
- proto: tcp
ports:
- 22
cidr_ip: 0.0.0.0/0
rule_desc: allow all on port 22
Create Elastic Load Balancers
The elb_application_lb
module helps you create an Elastic Load Balancer (ELB) with a single module:
# create elb
- name: Create Amazon ELB
amazon.aws.ec2_elb_lb:
profile: "{{ aws_boto_profile }}"
name: "{{ aws_elb_app_lb }}"
region: "{{ aws_region }}"
zones:
- "{{ ap_zone1 }}"
- "{{ ap_zone2 }}"
listeners:
- protocol: http
load_balancer_port: 80
instance_port: 80
proxy_protocol: True
state: present
register: elbcreated
Install and configure an application
Once your infrastructure is ready and running, you need to deploy the application and configure it. Ansible is very good at this:
- name: Deploy Webserver to EC2 instances
hosts: "{{ inventory_webgroup }}"
remote_user: ec2-user
become: true
tasks:
- name: Deploy Web service
include_role:
name: deploy-web-server
An example: Build a web server infrastructure and application
In this demo, you deploy a full-stack infrastructure including:
- Security groups
- ELB target groups
- Application load balancer
- Dedicated key pair
- 2x EC2 instance
- Configured web server with default website content
The entire infrastructure code is available in my GitHub repository for reference.
Connect to AWS using credentials
Configure the AWS credentials that Ansible will use and automate the infrastructure management. This is a standard process, and you can refer to "How to install and configure AWS command-line interface (CLI)" to configure them.
If you have multiple credentials configured, use the correct profile inside your playbook as profile: "{{ aws_boto_profile }}"
where aws_boto_profile
is the variable you configured as the profile name.
Execute the Ansible playbook
Enter the following to tell Ansible to create all the resources and show the ELB's URL to access the website:
$ ansible-playbooks aws-infra-provisioning.yaml
Destroy the infrastructure
An IaC handles the infrastructure's entire lifecycle, so you can create a separate playbook for destroying the infrastructure. Once you finish testing, call the aws-infra-destroy.yaml
playbook to destroy the entire infrastructure you created:
$ ansible-playbooks aws-infra-destroy.yaml
Wrap up
By using Ansible, you can manage AWS or any other public or private cloud platforms and resources. Make sure you follow all the best practices and validations to handle provisioning and destroying.
Gineesh Madapparambath
Gineesh Madapparambath is a Platform & DevOps Consultant at Red Hat Singapore, specializing in automation and containerization with Ansible and OpenShift. More about me