Ansible ec2_elb_lb HTTPS to HTTP error - amazon-web-services

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

ansible undefined variable for a play while creating an ec2 instance

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.

Creating and Assigning Public IP to the EC2 instance created with ansible

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.

Ansible EC2: Only Amazon VPC security groups may be used with this operation

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}

How to define an AWS ELB in Ansible with a listener that has a range of ports

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}}"

Ansible: allocating an elastic ip to newly created instance

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