error with ec2 inventory variable

Hi,

I am getting this error (part of a playbook included):

http://pastie.org/7709606

Work flow:
I will create nodes on EC2 and install them.
Everything goes very until this line:

when: “‘master’ in ec2_tag_Name and hadoop_exists.rc == 1”

ec2_tag_Name doesn’t seem to exist.

But when I run the same playbook and use the same machines (installed in the previous partial unsuccessful run) it works as expected.

ec2_tag_Name exists and playbook finishes just fine.

In both cases an output of a command:

I might be misinterpreting what you are trying to do but I don’t see where ec2_tag_Name is defined as a variable. It looks like you want to reference the group name and key off that somehow, tag_Name_ANS-Test You’d do this by referencing: ${groups.tag_Name_ANS-Test}.

I tried it still no luck.

  • action: debug msg=“EC2 tag ${group.ec2_tag_Name} ${hadoop_dir_src}”

TASK: [debug msg=“EC2 tag ${group.ec2_tag_Name} …/files/hadoop/cdh4”] ********
ok: => {“item”: “”, “msg”: “EC2 tag ${group.ec2_tag_Name} …/files/hadoop/cdh4”}
ok: => {“item”: “”, “msg”: “EC2 tag ${group.ec2_tag_Name} …/files/hadoop/cdh4”}

=> Conditional expression must evaluate to True or False: {% if ‘master’ in ${group.sec2_tag_Name} %} True {% else %} False {% endif %}

Strange is that this:
{% if ‘master’ in sec2_tag_Name %}

works.

You have ec2 in one and sec2 in the other.

Suspect it is that :slight_smile:

Those types of bugs are embarrassing :).

A summary first:

ec2_tag_Name works in post run - create instances in one playbook run and install them in second.
group.ec2_tag_Name doesn’t exist

ec2_tag_Name is not evaluated in debug msg, but it’s in debug output.

when: “‘master’ in ${group.ec2_tag_Name}” is failing, but I am pretyy sure it woked yesterday => I should not be working with dev branch :slight_smile:

Anyway the issues is still there (I am using devel branch):

Run with group.ec2_tag_Name:

  • name: format namenode
    command: su hdfs -c “/usr/bin/hadoop namenode -format -nonInteractive” create=${hadoop_dir_nn}/current
    when: “‘master’ in ${group.ec2_tag_Name}”

It is hard to help over email at a decent rate here :slight_smile:

I would not use the $foo variables in templates, even in 1.X, but obviously the point of 1.2 is to allow the same variable logic we could always use in templates to be used in mainline playbooks.
There should be no reason to not run 1.2 at this time – it’s quite stable.

So anyway, I would in any version rewrite this:

{% if ‘master’ in ${group.ec2_tag_Name} %}

As:

{% if ‘master’ in group.ec2_tag_Name % }

This makes it a valid Jinja2 statement and doesn’t rely on the $foo replacement stuff.

Obviously if you want to debug available variables, you can just do this, and I would recommend it:

{% groups | to_nice_json %}
{% hostvars | to_nice_json %}

IRC chat have not solved anything :slight_smile: but just to let you now:

this works:
when: “‘master’ in ec2_tag_Name”

this doesn’t:
when: “‘master’ in ${ec2_tag_Name}”

Real problem is still this error:
http://pastie.org/7725328

Filip

ec2 tag name is a string not a list of groups.

And using 1.2, all that outer quoting is unnecessary.

ec2 tag name is a string not a list of groups.

Yes, “in” works for list, strings …
I just thought that:
${ec2_tag_Name} ← save way how to get variable.

In this case ${ec2_tag_Name} doesn’t work.

BTW, what you have is not a variable. Not supposed to work. Happy to discuss on IRC.

groups[‘ec2_tag_Name’] is the list of matching hosts in the group.

Finally I found enough time to look into it - I spent few hours with pdb :).

ec2_tag_Name is a variable from ec2 script - you get those from here:

inject.update(self.playbook.inventory.get_variables(host))

The problem was that I use this to register ec2 variable:

  • name: add it to the special group
    local_action: add_host hostname=${inst_res.instances[0].publis_ip} groupname=${target_group}

ec2.py does not return inventory host vars by public_ip (it returns {})

I have changed publis_ip to public_dns_name and it works.

The rest of the ansible was able to work with public ip just fine.

Filip

Hi Filip,

You can run the EC2 inventory file and list out all variables for a host by doing this:

$ /etc/ansible/hosts --host ec2-50-112-79-155.us-west-2.compute.amazonaws.com
{
“ec2__in_monitoring_element”: false,
“ec2__previous_state”: “”,
“ec2_ami_launch_index”: “0”,
“ec2_architecture”: “x86_64”,
“ec2_client_token”: “d79a7c98-10f7-4b3e-be3d-426098331041”,
“ec2_dns_name”: “ec2-50-112-79-155.us-west-2.compute.amazonaws.com”,
“ec2_ebs_optimized”: false,
“ec2_eventsSet”: “”,
“ec2_group_name”: “”,
“ec2_hypervisor”: “xen”,
“ec2_id”: “i-b2c51888”,
“ec2_image_id”: “ami-ca1582fa”,
“ec2_instance_profile”: “”,
“ec2_instance_type”: “m1.xlarge”,
“ec2_ip_address”: “50.112.79.155”,
“ec2_item”: “”,
“ec2_kernel”: “aki-ace26f9c”,
“ec2_key_name”: “secretkey”,
“ec2_launch_time”: “2013-05-03T00:01:39.000Z”,
“ec2_monitored”: false,
“ec2_monitoring”: “”,
“ec2_persistent”: false,
“ec2_platform”: “”,
“ec2_private_dns_name”: “ip-10-253-43-92.us-west-2.compute.internal”,
“ec2_private_ip_address”: “10.253.43.92”,
“ec2_public_dns_name”: “ec2-50-112-79-155.us-west-2.compute.amazonaws.com”,
“ec2_ramdisk”: “”,
“ec2_reason”: “”,
“ec2_region”: “us-west-2”,
“ec2_requester_id”: “”,
“ec2_root_device_name”: “”,
“ec2_root_device_type”: “instance-store”,
“ec2_security_group_ids”: “sg-5b4e0b6b”,
“ec2_security_group_names”: “ElasticMapReduce-slave”,
“ec2_spot_instance_request_id”: “”,
“ec2_state_reason”: “”,
“ec2_subnet_id”: “”,
“ec2_tag_Name”: “EMR Cluster”,
“ec2_tag_aws_elasticmapreduce_instance-group-role”: “CORE”,
“ec2_tag_aws_elasticmapreduce_job-flow-id”: “j-122MBJ5QTIUJ1”,
“ec2_virtualization_type”: “paravirtual”,
“ec2_vpc_id”: “”
}

So in this case, ec2_ip_address is the variable for the public IP

Hope that helps.

Peter Sankauskas

Hi Peter,

Yes I know. And there is a list of variables in ec2 script.

My problem was that I was using public IP to register a server.

Example of the playbook:

-hostanme localhost

  • create EC2 host

  • register: add_host hostname=${inst_res.instances[
    0].publis_ip}

-hostanme just_created_hostname

  • try to use ec2 variable

FAIL

This is not a real playbook, please paste the actual one please.

ansible/bin/ansible-playbook playbooks/test.yml -vvv --private-key key.pem -i ansible/inventory/ -e “ec2_instance_name=ANSTEST1 target_group=tag_Name_ANSTEST1”

  • hosts: localhost
    connection: local
    user: root
    gather_facts: False

vars_files:

  • external_vars.yml
  • ec2_vars.yml

tasks:

  • name: spin it up
    local_action:
    module: ec2
    keypair: ${ec2_keypair}
    image: ami-xxxxxx
    instance_type: m1.small
    group: ${ec2_security_group}
    ec2_access_key: ${ec2_access_key}
    ec2_secret_key: ${ec2_secret_key}
    instance_tags: “{"Name":"${ec2_instance_name}-master"}”
    wait: yes
    count: 1
    register: inst_res

  • name: add it to a group
    local_action: add_host hostname=${inst_res.instances[0].public_dns_name} groupname=${target_group}

  • name: wait for the host
    local_action: wait_for host=${inst_res.instances[0].public_dns_name} port=22 delay=5 timeout=300

  • hosts: ${target_group}*

user: root
gather_facts: yes
vars:

  • hadoop_version: cdh4

tasks:

  • name: test hadoop_version {{hadoop_version}}
    shell: echo “${hadoop_version}${ec2_tag_Name}” > /tmp/test
    when: “‘master’ in ec2_tag_Name”