Variable is empty or no defined in Ansible

Viewed 104

When I run my playbook I see the following error:

fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: list object has no element 0\n\nThe e
rror appears to be in '/etc/ansible/loyalty/tasks/create_ec2_stage.yaml': line 63, column 7, but may\nbe elsewhere in the file depending on the exac
t syntax problem.\n\nThe offending line appears to be:\n\n      register: ec2_metadata\n    - name: Parse < JSON >\n      ^ here\n"} 

I run the playbook this way:

/usr/bin/ansible-playbook -i hosts --extra-vars "CARRIER=xx" tasks/create_ec2_stage.yaml

Here is my playbook:

---
- name: New EC2 instances
  hosts: localhost
  gather_facts: no
  vars_files:
    - /etc/ansible/loyalty/vars/vars.yaml
  tasks:
    - name: Run EC2 Instances
      amazon.aws.ec2_instance:
        name: "new-{{ CARRIER }}.test"
        aws_secret_key: "{{ ec2_secret_key }}"
        aws_access_key: "{{ ec2_access_key }}"
        region: us-east-1
        key_name: Kiu
        instance_type: t2.medium
        image_id: xxxxxxxxxxxxx
        wait: yes
        wait_timeout: 500
        volumes:
          - device_name: /dev/xvda
            ebs:
              volume_type: gp3
              volume_size: 20
              delete_on_termination: yes
        vpc_subnet_id: xxxxxxxxxxxx
        network:
          assign_public_ip: no
        security_groups: ["xxxxxxxxxx", "xxxxxxxxxxx", "xxxxxxxxxxxxxx"]
        tags:
          Enviroment: TEST
        count: 1
    - name: Pause Few Seconds
      pause:
        seconds: 20
        prompt: "Please wait"
    - name: Get Information for EC2 Instances
      ec2_instance_info:
        region: us-east-1
        filters:
          "tag:Name": new-{{ CARRIER }}.test
      register: ec2_metadata
    - name: Parse JSON
      set_fact:
        ip_addr: "{{ ec2_metadata.instances[0].network_interfaces[0].private_ip_address }}"

If I create a slightly smaller playbook to query the private IP address of an existing instance, I don’t see any error.

---
- name: New EC2 Instances
  hosts: localhost
  gather_facts: no
  vars_files:
    - /etc/ansible/loyalty/vars/vars.yaml
  vars:
    pwd_alias: "{{ lookup('password', '/dev/null length=15 chars=ascii_letters') }}"
    CARRIER_UPPERCASE: "{{ CARRIER | upper }}"
  tasks:
    - set_fact:
       MY_PASS: "{{ pwd_alias }}"
    - name: Get EC2 info
      ec2_instance_info: 
        region: us-east-1
        filters:
          "tag:Name": new-{{ CARRIER }}.stage
      register: ec2_metadata
    - name: Parsing JSON
      set_fact: 
        ip_addr: "{{ ec2_metadata.instances[0].network_interfaces[0].private_ip_address }}"
    - name: Show Result
      debug:
        msg: "{{ ip_addr }}"

Results in

TASK [Show Result] ******************************************************
ok: [localhost] => {
    "msg": "172.31.x.x"
}

I am creating an EC2 instance on Amazon and querying the private IP to use that IP on other services like router53 and Cloudflare, other tasks do not add them because the error is in the fact.

1 Answers

You don't have to query AWS with the ec2_instance_info module since the module amazon.aws.ec2_instance already returns you the newly created EC2 when the parameter wait is set to yes, as it is in your case.

You just need to register the return of this task.

So, given the two tasks:

- name: Run EC2 Instances
  amazon.aws.ec2_instance:
    name: "new-{{ CARRIER }}.test"
    aws_secret_key: "{{ ec2_secret_key }}"
    aws_access_key: "{{ ec2_access_key }}"
    region: us-east-1
    key_name: Kiu
    instance_type: t2.medium
    image_id: xxxxxxxxxxxxx
    wait: yes
    wait_timeout: 500
    volumes:
      - device_name: /dev/xvda
        ebs:
          volume_type: gp3
          volume_size: 20
          delete_on_termination: yes
    vpc_subnet_id: xxxxxxxxxxxx
    network:
      assign_public_ip: no
    security_groups: ["xxxxxxxxxx", "xxxxxxxxxxx", "xxxxxxxxxxxxxx"]
    tags:
      Enviroment: TEST
    count: 1
  register: ec2

- set_fact:
    ip_addr: "{{ ec2.instance[0].private_ip_address }}"

You should have the private IP address of the newly created EC2 instance.

Related