I have managed to successfully create an ELB using this playbook:
- name: Create VPC network
ec2_elb_lb:
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
name: "ElasticLoadBalancer"
region: us-east-1
state: present
subnets: "{{ Subnet.SubnetId }}"
listeners:
- protocol: http
load_balancer_port: 80
instance_port: 80
register: elb
- debug: msg="{{ elb }}"
But I also need to add HTTPS inbound and HTTP outbound, so I added an extra listener as per the ec2_elb_lb module example:
- name: Create VPC network
ec2_elb_lb:
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
name: "ElasticLoadBalancer"
region: us-east-1
state: present
subnets: "{{ Subnet.SubnetId }}"
listeners:
- protocol: http
load_balancer_port: 80
instance_port: 80
- protocol: https
load_balancer_port: 443
instance_protocol: http
instance_port: 80
register: elb
- debug: msg="{{ elb }}"
After running the above playbook I get the following message:
failed: [localhost] => {"failed": true, "parsed": false}
Traceback (most recent call last):
File "/root/.ansible/tmp/ansible-tmp-1448959476.82-159664399600608/ec2_elb_lb", line 2519, in <module>
main()
File "/root/.ansible/tmp/ansible-tmp-1448959476.82-159664399600608/ec2_elb_lb", line 693, in main
elb_man.ensure_ok()
File "/root/.ansible/tmp/ansible-tmp-1448959476.82-159664399600608/ec2_elb_lb", line 292, in ensure_ok
self._create_elb()
File "/root/.ansible/tmp/ansible-tmp-1448959476.82-159664399600608/ec2_elb_lb", line 397, in _create_elb
scheme=self.scheme)
File "/usr/lib/python2.7/site-packages/boto/ec2/elb/__init__.py", line 230, in create_load_balancer
params['Listeners.member.%d.SSLCertificateId' % i] = listener[4]
IndexError: tuple index out of range
FATAL: all hosts have already failed -- aborting
ansible --version
ansible 1.9.4
If you want to provide HTTPS on the ELB then you need to provide an SSL certificate as well.
So your ec2_elb_lb task should instead look like:
- name: Create VPC network
ec2_elb_lb:
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
name: "ElasticLoadBalancer"
region: us-east-1
state: present
subnets: "{{ Subnet.SubnetId }}"
listeners:
- protocol: http
load_balancer_port: 80
instance_port: 80
- protocol: https
load_balancer_port: 443
instance_protocol: http
instance_port: 80
ssl_certificate_id: "arn:aws:iam::123456789012:server-certificate/company/servercerts/ProdServerCert"
register: elb
- debug: msg="{{ elb }}"
Related
I am getting the undefined variable error while creating EC2 instance in AWS Cloud with Ansible playbook.
My Ansible version is 2.9.
My Playbook:
---
- name: Running AWS EC2 Play ...
hosts: localhost
connection: local
gather_facts: yes
tasks:
- include_vars: aws_vars.yml
- name: Setting up the Security Group for new instance
ec2_group:
name: "{{ aws_hostname }}-nsg"
description: Allowing Traffic on port 22 and 80
region: "{{ aws_region }}"
aws_secret_key: "{{ SecretKey }}"
aws_access_key: "{{ AccessKey }}"
rules:
- proto: tcp
from_port: 22
to_port: 22
cidr_ip: 0.0.0.0/0
- proto: tcp
from_port: 80
to_port: 80
cidr_ip: 0.0.0.0/0
rules_egress:
- proto: all
cidr_ip: 0.0.0.0/0
vpc_id: "{{ aws_vpc_id }}"
- name: Spinning up new aws ec2 instance
ec2:
aws_access_key: "{{ AccessKey }}"
aws_secret_key: "{{ SecretKey }}"
image: "{{ aws_image_id }}"
instance_type: "{{ aws_instance_type }}"
instance_tags: { "Name":"{{ aws_hostname }}", "Vendor": "Amazon" }
key_name: "{{ aws_instance_key }}"
assign_public_ip: no
count: 1
wait: yes
wait_timeout: 500
region: "{{ aws_region }}"
volumes:
- device_name: "{{ aws_device_name }}"
device_type: "{{ aws_device_type }}"
volume_size: "{{ aws_volume_size }}"
delete_on_termination: true
vpc_subnet_id: "{{ aws_subnet_id }}"
group: "{{ aws_hostname }}-nsg"
user_data: hostnamectl set-hostname "{{ aws_hostname }}"
register: ec2_result
- debug:
var: ec2_result
- name: Wait for SSH to come up
wait_for:
host: '{{ private_ip }}'
port: 22
delay: 60
timeout: 320
state: started
loop: '{{ ec2_result.instances }}'
- name: Add all instance public IPs to host group
add_host:
hostname: '{{ private_ip }}'
groups: ec2_hosts
loop: '{{ ec2_result.instances }}'
The error
TASK [Wait for SSH to come up] ******************************************************************************************************************************
task path: /home/user1/create_awsVM.yml:61
fatal: [localhost]: FAILED! => {
"msg": "The task includes an option with an undefined variable. The error was: 'private_ip' is undefined\n\nThe error appears to be in '/home/user1/create_awsVM.yml': line 61, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Wait for SSH to come up\n ^ here\n"
}
PLAY RECAP **************************************************************************************************************************************************
localhost : ok=5 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
What I also tried:
- name: Wait for SSH to come up
wait_for:
host: '{{ item.private_ip }}'
port: 22
delay: 60
timeout: 320
state: started
loop: '{{ ec2_result.instances }}'
I used item as item.private_ip as thought it might work with loop but no luck.
Any help will be much appreciated.
while creating a AWS instance from the playbook i was trying to attach an elastic ip with the server. and am getting this error.
fatal: [localhost]: FAILED! => {
"msg": "'dict object' has no attribute 'instance_ids'"
}
to retry, use: --limit #/home/ubuntu/aws.retry
name: aws instance creating
hosts: local
connection: local
gather_facts: True
vars:
os_image: ami-063aa838bd7631e0b
location: us-west-1
pem: recippeeps-c
vpc_subnet: subnet-fc5664a7
server_name: sagar-test
instance_type: t2.micro
firewall_name: sagar
description: sagar_test_rule
count: 1
tasks:
- name: ec2 security group
ec2_group:
name: "{{firewall_name}}"
region: "{{location}}"
description: "{{description}}"
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
- proto: tcp
from_port: 443
to_port: 443
cidr_ip: 0.0.0.0/0
register: firewall
- name: Debug firewall facts
debug: msg="{{firewall}}"
- name: creating AWS instance
ec2:
key_name: "{{pem}}"
instance_type: "{{instance_type}}"
region: "{{location}}"
image: "{{os_image}}"
termination_protection: no
group_id: "{{firewall.group_id}}"
wait: true
count: "{{count}}"
instance_tags:
Name: "{{server_name}}"
state: present
vpc_subnet_id: "{{vpc_subnet}}"
assign_public_ip: yes
register: ec2
- name: Debug EC2 facts
debug: msg="{{ec2}}"
- name: Providing a Static IP
ec2_eip:
in_vpc: yes
reuse_existing_ip_allowed: yes
region: "{{location}}"
device_id: "{{ec2.instance_ids}}"
wait_timeout: "20"
The error is clear
"'dict object' has no attribute 'instance_ids'"
when you try to use it
device_id: "{{ ec2.instance_ids }}"
You registered and printed ec2
register: ec2
- name: Debug EC2 facts
debug: msg="{{ ec2 }}"
Take a look where instance_ids is, or post ec2.
I'm working through this Best way to launch aws ec2 instances with ansible
and have this task
- name: Create a security group
local_action:
module: ec2_group
name: "{{ security_group }}"
description: Security Group for webserver Servers
region: "{{ region }}"
rules:
- proto: tcp
from_port: 22
to_port: 22
cidr_ip: 0.0.0.0/0
- proto: tcp
from_port: 80
to_port: 80
cidr_ip: 0.0.0.0/0
- proto: tcp
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: basic_firewall
However running it returns
TASK [Create a security group] *****************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: <Response><Errors><Error><Code>InvalidParameterValue</Code><Message>Only Amazon VPC security groups may be used with this operation.</Message></Error></Errors><RequestID>12345678-deb3-441e-8c61-225dad8cc08b</RequestID></Response>
fatal: [localhost -> localhost]: FAILED! => {"changed": false, "failed": true, "module_stderr": "Traceback (most recent call last):\n File \"/var/folders/cp/d6jyx8b53xx3603wg2j4qfpc0000gn/T/ansible_IJzYY4/ansible_module_ec2_group.py\", line 487, in <module>\n main()\n File \"/var/folders/cp/d6jyx8b53xx3603wg2j4qfpc0000gn/T/ansible_IJzYY4/ansible_module_ec2_group.py\", line 439, in main\n cidr_ip=thisip)\n File \"/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/boto/ec2/connection.py\", line 3245, in authorize_security_group_egress\n params, verb='POST')\n File \"/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/boto/connection.py\", line 1227, in get_status\n raise self.ResponseError(response.status, response.reason, body)\nboto.exception.EC2ResponseError: EC2ResponseError: 400 Bad Request\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Response><Errors><Error><Code>InvalidParameterValue</Code><Message>Only Amazon VPC security groups may be used with this operation.</Message></Error></Errors><RequestID>12345678-deb3-441e-8c61-225dad8cc08b</RequestID></Response>\n", "module_stdout": "", "msg": "MODULE FAILURE", "rc": 0}
Any suggestions?
Define vpc_id under which sg will be launch.
ec2_group:
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
description: staging-dj-sg
name: (sg-name)
region: "{{ aws_region }}"
rules:
-
from_port: "80"
proto: tcp
to_port: "80"
cidr_ip: (ip-range)
vpc_id: "{{ vpc_id }}" #### Define VPC ID
name: "Create Security Group"
register: {name}
I'm creating an AWS ELB that will sit in front of two EC2 instances using Ansible. This ELB will listen on the usual SSH port and a range between 6000 and 6100.
- name: Create ELB for web servers
local_action:
module: ec2_elb_lb
name: "{{ elb_web }}"
state: present
zones: "{{ availability_zones }}"
tags:
Name: "{{ elb_web }}"
listeners:
- protocol: http
load_balancer_port: 80
instance_port: 80
proxy_protocol: True
- protocol: tcp
from_port????
cross_az_load_balancing: "yes"
security_group_names: "{{ security_group_web }}"
wait: yes
register: elb_web_result
until: "elb_web_result.module_stderr is not defined"
retries: 2
delay: 1
How to define an AWS ELB in Ansible with a listener that has a range of ports instead of port by port? Or maybe even better, how to I define that anything coming from a specific security group should be listened to and sent to the instances?
Thanks!
Very odd task indeed, but if you really do want to create a load balancer with such a huge port range, you can use this trick:
- set_fact:
listener:
protocol: tcp
load_balancer_port: "{{item}}"
instance_port: "{{item}}"
with_sequence: start=6000 end=6100
register: listeners_range
- set_fact:
listeners_range: "{{ listeners_range.results | map(attribute='ansible_facts.listener') | list }}"
- debug: var=listeners_range
This will make variable listeners_range with list of items ranged 6000-6100:
protocol: tcp
load_balancer_port: "{{item}}"
instance_port: "{{item}}"
So you can call ec2_elb_lb and specify listeners: "{{listeners_range}}"
I am creating a new instance with ansible and want to associate an elastic ip to it. What value should i write in instance_id? instance_id: "{{ newinstance.instances[0].id }}" ??? But this value seems to be wrong, because i have an output after checking:
TASK: [Allocating elastic IP to instance] *************************************
fatal: [localhost] => One or more undefined variables: 'dict object' has no attribute 'instances'
---
- name: Setup an EC2 instance
hosts: localhost
connection: local
tasks:
- name: Create an EC2 machine
ec2:
aws_access_key: my_access_key
aws_secret_key: my_secret_key
key_name: my_key
instance_type: t1.micro
region: us-east-1
image: some_ami
wait: yes
vpc_subnet_id: my_subnet
assign_public_ip: yes
register: newinstance
- name: Allocating elastic IP to instance
ec2_eip:
aws_access_key: my_access_key
aws_secret_key: my_secret_key
in_vpc: yes
reuse_existing_ip_allowed: yes
state: present
region: us-east-1
instance_id: "{{ newinstance.instances[0].id }}"
register: instance_eip
- debug: var=instance_eip.public_ip
- name: Wait for SSH to start
wait_for:
host: "{{ newinstance.instances[0].private_ip }}"
port: 22
timeout: 300
sudo: false
delegate_to: "127.0.0.1"
- name: Add the machine to the inventory
add_host:
hostname: "{{ newinstance.instances[0].private_ip }}"
groupname: new
What should i put instead "{{ newinstance.instances[0].id }}"? The same question is about "{{ newinstance.instances[0].private_ip }}".
You are basically trying to parse data from the JSON output of Ansible task which is given to your variable. instance_ids is an array and child of newinstance JSON. Similarly private_ip is a direct child of newinstance
---
- name: Setup an EC2 instance
hosts: localhost
connection: local
tasks:
- name: Create an EC2 machine
ec2:
aws_access_key: my_access_key
aws_secret_key: my_secret_key
key_name: my_key
instance_type: t1.micro
region: us-east-1
image: some_ami
wait: yes
vpc_subnet_id: my_subnet
assign_public_ip: yes
register: newinstance
- name: Allocating elastic IP to instance
ec2_eip:
aws_access_key: my_access_key
aws_secret_key: my_secret_key
in_vpc: yes
reuse_existing_ip_allowed: yes
state: present
region: us-east-1
instance_id: "{{ newinstance.instance_ids[0] }}"
register: instance_eip
- debug: var=instance_eip.public_ip
- name: Wait for SSH to start
wait_for:
host: "{{ newinstance.private_ip }}"
port: 22
timeout: 300
sudo: false
delegate_to: "127.0.0.1"
- name: Add the machine to the inventory
add_host:
hostname: "{{ newinstance.private_ip }}"
groupname: new