Ansible - AWS : creating an ELB & registers an EC2 instance from the ELB
bogotobogo.com site search:
Ansible 2.0
Introduction
Ansible is a configuration management tool, and unlike Chef and Puppet, it uses a push mechanism to push the desired changes on the servers using ssh-agent.
In this article, we'll create an EC2 instance, ELB and attach the instance to ELB.
Requirements
Requirements (on host that executes module):
- python >= 2.6
- boto - Ansible's EC2 module uses python-boto library to call AWS API, and boto needs AWS credentials in order to function. So we need the boto installed on our local host.
Though there are many ways to set our AWS credentials, in this tutorial, we'll create a file under our user home folder (~/.boto):
[Credentials] AWS_ACCESS_KEY_ID=KID...CWU AWS_SECRET_ACCESS_EY=3qv...DSP
site.yml
Here is our playbook (site.yml) to create an instance:
--- - name: A simple Load Balanced AWS server hosts: localhost connection: local gather_facts: False tasks: - name: Create security group ec2_group: name: "demo_security_group" description: "demo security group" region: "{{ region }}" rules: - proto: tcp # ssh from_port: 22 to_port: 22 cidr_ip: 0.0.0.0/0 - proto: tcp # http from_port: 80 to_port: 80 cidr_ip: 0.0.0.0/0 - proto: tcp # https from_port: 443 to_port: 443 cidr_ip: 0.0.0.0/0 rules_egress: - proto: all cidr_ip: 0.0.0.0/0 register: demo_firewall - name: Create an EC2 instance ec2: key_name: "{{ pem_key }}" region: "{{ region }}" group_id: "{{ demo_firewall.group_id }}" instance_type: "{{ instance_type }}" image: "{{ ami }}" wait: yes instance_tags: env: "{{ env }}" count_tag: env exact_count: 1 vpc_subnet_id: subnet-66d25311 assign_public_ip: yes register: ec2 - name: wait for the servers to appear on the network wait_for: host={{ item.public_dns_name }} port=22 delay=10 timeout=180 state=started with_items: ec2.tagged_instances - name: add server ip addresses to hosts group add_host: hostname={{ item.public_ip }} groupname=launched with_items: ec2.tagged_instances - name: webservers (installs nginx ...) hosts: launched remote_user: ubuntu become: true become_method: sudo gather_facts: True roles: - web - name: spin up the load balancer and add the servers to it hosts: 127.0.0.1 connection: local gather_facts: False tasks: - name: setup a simple load balancer ec2_elb_lb: name: aws-elb-demo state: present region: us-east-1 zones: - us-east-1a listeners: - protocol: http load_balancer_port: 80 instance_port: 80 register: aws-elb-demo - name: add the webservers to the load balancer local_action: ec2_elb args: instance_id: "{{ item.id }}" ec2_elbs: aws-elb-demo state: present region: us-east-1 with_items: ec2.tagged_instances
Running the playbook
Let's run the playbook:
$ ansible-playbook site.yml --private-key /home/k/.ssh/einsteinish.pem [WARNING]: provided hosts list is empty, only localhost is available PLAY [A simple Load Balanced AWS server] *************************************** TASK [Create security group] *************************************************** ok: [localhost] TASK [Create an EC2 instance] ************************************************** ok: [localhost] TASK [wait for the servers to appear on the network] *************************** ok: [localhost] => (item={u'kernel': None, u'root_device_type': u'ebs', u'private_dns_name': u'ip-172-31-44-178.ec2.internal', u'public_ip': u'52.90.145.182', u'private_ip': u'172.31.44.178', u'id': u'i-0503d03ac7b282a0c', u'ebs_optimized': False, u'state': u'running', u'virtualization_type': u'hvm', u'architecture': u'x86_64', u'ramdisk': None, u'block_device_mapping': {u'/dev/sda1': {u'status': u'attached', u'delete_on_termination': True, u'volume_id': u'vol-0ee7cb23a0ba4c219'}}, u'key_name': u'einsteinish', u'image_id': u'ami-49c9295f', u'tenancy': u'default', u'groups': {u'sg-480a6d37': u'demo_security_group'}, u'public_dns_name': u'ec2-52-90-145-182.compute-1.amazonaws.com', u'state_code': 16, u'tags': {u'env': u'demo'}, u'placement': u'us-east-1c', u'ami_launch_index': u'0', u'dns_name': u'ec2-52-90-145-182.compute-1.amazonaws.com', u'region': u'us-east-1', u'launch_time': u'2017-04-03T04:29:09.000Z', u'instance_type': u't2.nano', u'root_device_name': u'/dev/sda1', u'hypervisor': u'xen'}) TASK [add server ip addresses to hosts group] ********************************** changed: [localhost] => (item={u'kernel': None, u'root_device_type': u'ebs', u'private_dns_name': u'ip-172-31-44-178.ec2.internal', u'public_ip': u'52.90.145.182', u'private_ip': u'172.31.44.178', u'id': u'i-0503d03ac7b282a0c', u'ebs_optimized': False, u'state': u'running', u'virtualization_type': u'hvm', u'architecture': u'x86_64', u'ramdisk': None, u'block_device_mapping': {u'/dev/sda1': {u'status': u'attached', u'delete_on_termination': True, u'volume_id': u'vol-0ee7cb23a0ba4c219'}}, u'key_name': u'einsteinish', u'image_id': u'ami-49c9295f', u'tenancy': u'default', u'groups': {u'sg-480a6d37': u'demo_security_group'}, u'public_dns_name': u'ec2-52-90-145-182.compute-1.amazonaws.com', u'state_code': 16, u'tags': {u'env': u'demo'}, u'placement': u'us-east-1c', u'ami_launch_index': u'0', u'dns_name': u'ec2-52-90-145-182.compute-1.amazonaws.com', u'region': u'us-east-1', u'launch_time': u'2017-04-03T04:29:09.000Z', u'instance_type': u't2.nano', u'root_device_name': u'/dev/sda1', u'hypervisor': u'xen'}) PLAY [webservers (installs nginx ...)] ***************************************** TASK [setup] ******************************************************************* ok: [52.90.145.182] TASK [web : Installs nginx web server] ***************************************** changed: [52.90.145.182] TASK [web : Upload default index.html for host] ******************************** changed: [52.90.145.182] RUNNING HANDLER [web : start nginx] ******************************************** ok: [52.90.145.182] PLAY [spin up the load balancer and add the servers to it] ********************* TASK [setup a simple load balancer] ******************************************** ok: [localhost] TASK [add the webservers to the load balancer] ********************************* changed: [localhost -> localhost] => (item={u'kernel': None, u'root_device_type': u'ebs', u'private_dns_name': u'ip-172-31-44-178.ec2.internal', u'public_ip': u'52.90.145.182', u'private_ip': u'172.31.44.178', u'id': u'i-0503d03ac7b282a0c', u'ebs_optimized': False, u'state': u'running', u'virtualization_type': u'hvm', u'architecture': u'x86_64', u'ramdisk': None, u'block_device_mapping': {u'/dev/sda1': {u'status': u'attached', u'delete_on_termination': True, u'volume_id': u'vol-0ee7cb23a0ba4c219'}}, u'key_name': u'einsteinish', u'image_id': u'ami-49c9295f', u'tenancy': u'default', u'groups': {u'sg-480a6d37': u'demo_security_group'}, u'public_dns_name': u'ec2-52-90-145-182.compute-1.amazonaws.com', u'state_code': 16, u'tags': {u'env': u'demo'}, u'placement': u'us-east-1c', u'ami_launch_index': u'0', u'dns_name': u'ec2-52-90-145-182.compute-1.amazonaws.com', u'region': u'us-east-1', u'launch_time': u'2017-04-03T04:29:09.000Z', u'instance_type': u't2.nano', u'root_device_name': u'/dev/sda1', u'hypervisor': u'xen'}) PLAY RECAP ********************************************************************* 52.90.145.182 : ok=4 changed=2 unreachable=0 failed=0 localhost : ok=6 changed=2 unreachable=0 failed=0
where the "einsteinish.pem" is my private key.
Since we installed nginx, we should see a default page
Source
Github source available here.
Here are other files.
web/tasks/main.yml:
- name: Installs nginx web server apt: pkg=nginx state=installed update_cache=true notify: - start nginx - name: Upload default index.html for host copy: src=static_files/index.html dest=/usr/share/nginx/www/ mode=0644
web/handlers/main.yml:
- name: start nginx service: name=nginx state=started
web/static_files/main.yml:
<html> <head> <title>This is a sample page</title> </head> <body> <h1>Here is a heading!</h1> <p>Here is a regular paragraph. Wow!</p> </body> </html>
group_vars/all:
region: us-east-1 instance_type: t2.nano ami: ami-49c9295f # Ubuntu 14.04 LTS app_code_user: "ubuntu" # remote user env: demo pem_key: einsteinish # key.pem
Ansible 2.0
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization