I am launching one-off ec2 instance for development purposes and in the main playbook I am launching an EC2 instance then assigning an elastic IP. Once all of that is done I am configuring the server via a role. I am able to capture the elastic IP via register but how do I call it from the role? Or more specifically how can I call it in a configuration template from within the role that is applied?
In the template from within the role it doesn’t know about eiptest.public_ip so it fails and reading the docs it seems that var will be destroyed at the end of the play that calls the role. If I run ansible hostname -m setup I don’t see any entries for the elastic IP assigned to the instance.
I’ve tried a number of things and read through the docs but not having much luck. I would like to keep the roles separate from the plays that launch the instances if at all possible.
Quick correction on this. I pasted the wrong data where it says “name: allocate a new elastic IP without associating it to anything” The play actually looks like this:
name: Associate a new Elastic IP to instance
ec2_eip: region=us-east-1 in_vpc=yes “instance_id={{ item }}”
with_items: ec2.instance_ids
register: eiptest
Perhaps I’m not completely following the question:
" I am able to capture the elastic IP via register but how do I call it from the role?"
Basically any variable already registered can be used like “{{ foo }}” in subsequent roles/tasks/whatever – so maybe you could help me understand where the point of confusion is?
I have a playbook that launches an EC2 instance and associates an elastic IP to that instance I then use register to capture that IP:
name: Associate a new Elastic IP to instance
ec2_eip: region=us-east-1 in_vpc=yes “instance_id={{ item }}”
with_items: ec2.instance_ids
register: eiptest
I used the debug technique to print out the IP just to make sure it was working:
name: Output the IP
debug: msg=“The elastic IP is {{ eiptest }}”
Here’s the output:
TASK: [Output the IP] *********************************************************
ok: [localhost] => {
“msg”: “The elastic IP is {‘msg’: ‘All items completed’, ‘changed’: True, ‘results’: [{u’public_ip’: u’255.100.104.57’, ‘item’: u’i-32d230d2’, u’changed’: True, ‘invocation’: {‘module_name’: u’ec2_eip’, ‘module_args’: u’region=us-east-1 in_vpc=yes "instance_id=asdfadf"'}}]}”
}
I tried a number of things and for some reason I can’t get it to print “The elastic IP is 255.100.104.57” using “The elastic IP is {{ eiptest.public_ip }}”. I had it working before but now I can only get it to dump the full dict above.
In any case at the end of the play I call the role which attempts to use a j2 template to put a config in place. From the configuration file:
external-ip=“{{ eiptest.public_ip }}”
And the error message:
ASK: [boom | Copy boom configuration] ****************************************
fatal: [10.10.10.10] => {‘msg’: “AnsibleUndefinedVariable: One or more undefined variables: ‘eiptest’ is undefined”, ‘failed’: True}
Hope all of this makes sense. I am using version 1.7.2 currently.
Okay I fixed the first issue in my previous post so:
name: Output the IP
debug: msg=“The elastic IP is {{ eiptest.results[0].public_ip }}”
Now displays:
TASK: [Output the IP] *********************************************************
ok: [localhost] => {
“msg”: “The elastic IP is 255.10.10.10”
}
But it doesnt carry over when the role is run. I tried turning off gather_facts before the role is called thinking maybe it was being overwritten or discarded but that didn’t work either.
I am also having a similar issue where we run a script that generates an API key and I save the output to a register: but I can’t get the nested value of “key”. But I’ll save that for another post
Once I wrap my head around the best way to access data in lists / dicts properly via Ansible I’ll be off and running.
Looks good to me. But I am still fighting through this on my end.
It seems like it should be pretty straightforward.
Launch the instance
Allocate elastic IP then use the register keyword to save it to a var. (I even tried set_fact with no luck)
In the template add {{ var.public_ip }}.
It will print the correct IP during a playbook run using debug but when it gets to the point of building the config from the template it seems the variable no longer exists.
I am going to try some other things or just put everything in the same one-off play.
Alright I have no idea what I am missing here but this is not working.
I added everything from the role into the same playbook that launches the server and it still has no clue what the variable is when I try to use it in a j2 template.
Keep in mind here there are two stages to this playbook. The local actions that LAUNCH the ec2 instance and then I configure the remote instance that was launched. All in the same play. Whereas before I was just launching then calling a role to run on it. I create groupname=launched then when it comes time to configure I use hosts: launched and everything else works but my vars don’t carry over.
Here are the relevant bits:
name: Associate a new Elastic IP to instance
ec2_eip: region=us-east-1 in_vpc=yes “instance_id={{ item }}”
with_items: ec2.instance_ids
register: eiptest
name: Set elastic IP fact
set_fact: elasticIP=“{{ eiptest.results[0].public_ip }}”
name: Output the IP
debug: msg=“The elastic IP is {{ elasticIP }}” <— This prints out the IP properly. No problem. Example: “msg”: “The elastic IP is 104.104.104.104”
name: Add new instance to host group
local_action: add_host hostname={{ item.private_ip }} groupname=launched
with_items: ec2.instances
name: Wait for SSH to come up
local_action: wait_for host={{ item.private_ip }} port=22 delay=60 timeout=320 state=started
with_items: ec2.instances
After SSH comes up the play continues with the following:
name: Install and configure server
hosts: launched
remote_user: ec2-user
sudo: yes
tasks:
And finally IN the config file itself is this line:
external-ip=“{{ elasticIP }}” NOTE: I have tried many different quote styles here
And I get this error:
TASK: [Copy server configuration] ***********************************************
fatal: [10.10.10.10 => {‘msg’: “AnsibleUndefinedVariable: One or more undefined variables: ‘elasticIP’ is undefined”, ‘failed’: True}
fatal: [10.10.10.10] => {‘msg’: “AnsibleUndefinedVariable: One or more undefined variables: ‘elasticIP’ is undefined”, ‘failed’: True}