Reputation: 31
I created the following playbook using "old" EC2 Ansible module:
---
- name: Create Ec2 instances
hosts: localhost
become: False
# import the secret file
vars_files:
- secrets.yml
gather_facts: false
tasks:
# Block is a Group of Tasks combined together
- name: Get Info Block
block:
- name: Get Running instance Info
ec2_instance_info:
register: ec2info
- name: Print info
debug: var="ec2info.instances"
- name: Create EC2 Block
block:
- name: Launch ec2 instances
tags: create_ec2
ec2:
region: eu-west-1
key_name: ec2-tutorial
group: launch-wizard-1
instance_type: t2.micro
image: ami-04dd4500af104442f
wait: yes
wait_timeout: 500
count: 1
instance_tags:
name: appservers
os: ubuntu
monitoring: no
vpc_subnet_id: subnet-049055a2c1633c0eb
assign_public_ip: yes
aws_access_key: XXXX
aws_secret_key: YYYYYYY
register: ec2
delegate_to: localhost
- name : Add instance to host group
add_host:
hostname: "{{ item.public_ip }}"
groupname: launched
loop: "{{ ec2.instances }}"
- name: Wait for SSH to come up
local_action:
module: wait_for
host: "{{ item.public_ip }}"
port: 22
delay: 10
timeout: 120
loop: "{{ ec2.instances }}"
# By specifying never on the tag of this block,
# I let this block to run only when explicitely being called
tags: ['never', 'ec2-create']
It works correctly and I'm able to create and EC2 instance testing also the connection retrieving its public IP.
The problem is that EC2 is deprecated, so; I rewrote the same playbook using the new module ec2_instance
that doesn't return the public IP.
Since, I'm not able to test the connection, I temporarily put a - meta: end_play
, so that I can deploy instance.
This is the new playbook
---
- name: Create Ec2 instances
hosts: localhost
become: False
# import the secret file
vars_files:
- secrets.yml
gather_facts: false
tasks:
# Block is a Group of Tasks combined together
- name: Get Info Block
block:
- name: Get Running instance Info
ec2_instance_info:
register: ec2info
- name: Print info
debug: var="ec2info.instances"
# By specifying always on the tag,
# # I let this block to run all the time by module_default
# # this is for security to net create ec2 instances accidentally
tags: ['always', 'getinfoonly']
- name: Create EC2 Block
block:
- name: Launch ec2 instances
tags: create_ec2
ec2_instance:
name: "Test new Ansible ec2 module"
region: eu-west-1
#Availability zone is mutually excluded with vpc_subnet_id
#availability_zone: eu-west-1c
#key_name: ec2-tutorial
key_name: testec2key
security_group: launch-wizard-1
instance_type: t2.micro
image_id: ami-04dd4500af104442f
wait: yes
volumes:
- device_name: /dev/sdb
ebs:
volume_size: 8
delete_on_termination: true
#- device_name: /dev/sdb
# volume_type: gp2
# volume_size: 5
# delete_on_termination: true
wait_timeout: 500
# count not available is this new module
#count: 1
tags:
name: "Test"
os: AwsAmi
#vpc_subnet_id: subnet-049055a2c1633c0eb
vpc_subnet_id: subnet-08a394b8718bbff45
network:
assign_public_ip: true
#termination_protection: yes
#aws_access_key: XXXXXXX
#aws_secret_key: YYYYYYYYYYY
register: ec2
delegate_to: localhost
#- meta: end_play
- name: Add instance to host group
add_host:
hostname: "{{ item.public_ip }}"
groupname: launched
loop: "{{ ec2.instances }}"
- name: Wait for SSH to come up
local_action:
module: wait_for
host: "{{ item.public }}"
port: 22
delay: 10
timeout: 120
loop: "{{ ec2.instances }}"
# By specifying never on the tag of this block,
# I let this block to run only when explicitely being called
tags: ['never', 'ec2-create']
This is the error I get running playbook, commenting - meta: end_play
(that makes the playbook go on):
ansible-playbook aws-ec2-creationtst3.yml --connection=local --tags=ec2-create -e "ansible_python_interpreter=/home/marcoreale/aws-venv/bin/python3" --ask-vault-pass -vvvv TASK [Add instance to host group] ************************************************************************************** task path: /home/xxx/aws-venv/playbook/aws-ec2-create/aws-ec2-creationtst3.yml:70 fatal: [localhost]: FAILED! => { "msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'public_ip'\n\nThe error appears to be in '/home/marcoreale/aws-venv/playbook/aws-ec2-create/aws-ec2-creationtst3.yml': line 70, column 9, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Add instance to host group\n ^ here\n" }
Note: replacing item.public_ip
with item.private_ip
works but I need to test connection using the public IP.
Do you have any suggestion? How should I change my playbook to test the connection using the public IP?
Upvotes: 3
Views: 1539
Reputation: 1269
You want to set state: running
in your ec2_instance invocation. Basically what is happening is your wait is only until it achieves the state defined, and the default state does not wait for the public_ip to be assigned.
Upvotes: 5
Reputation: 39129
The documentation is pointing at the fact that the public IP address is now nested via the public_ip_address
property.
So, your task should work with
- name: Add instance to host group
add_host:
hostname: "{{ item.public_ip_address }}"
groupname: launched
loop: "{{ ec2.instances }}"
Upvotes: 0