Use id of AMI I have created as a variable in later tasks

I am trying to create a playbook which does the following:

  • creates an image of an AWS instance
  • copies the image to a different region
  • installs updates to the instance

I can do all of this apart from getting the AMI to copy to a different region. I’ve tried a few things but this is my current playbook (this is only for the AMI creation and copying, installing updates is handled separately).

`

  • hosts: webservers
    remote_user: ubuntu
    tasks:

  • name: create an ami
    ec2_ami:
    region: eu-west-2
    instance_id: i-0771a2e4289c057e9
    name: “{{ inventory_hostname }}-{{ ansible_date_time.iso8601_basic_short }}”
    tags:
    Name: “{{ inventory_hostname }}-{{ ansible_date_time.iso8601_basic_short }}”

  • name: set ID name
    set_fact:
    new_ami_name: ec2_ami.image_id

  • pause:
    seconds: 60

  • name: copy AMI to a different region
    ec2_ami_copy:
    source_region: eu-west-2
    source_image_id: “{{ new_ami_name }}”
    name: “{{ new_ami_name }}”
    region: eu-west-1
    `

For which the creation, setting fact, and pause work, but on the last part I get this error output:

`
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ClientError: An error occurred (InvalidAMIID.Malformed) when calling the CopyImage operation: Invalid id: “ec2_ami.image_id” (expecting “ami-…”)

`

I’ve tried a few different things I’m fairly new to Ansible, but basically I can’t figure out how to pass the image_id of the newly created AMI to the next play so that it can use this as the basis of the copying.

I can see clearly that it’s not registering the image_id as it’s saying it’s not in the expected “ami-” format, but I’m stuck from there.

After more searching I also tried this:

`

You need to wrap wrap the variable up in curly braces so that it is interpreted rather than taken literally.

I.e., where you have:
new_ami_id: ami.results[0].image_id

you need:
new_ami_id: "{{ ami.results[0].image_id }}"

Regards, K.

I had actually tried that already, and when I do I get this error:

“msg”: "The task includes an option with an undefined variable. The error was: ‘new_ami_id’ is undefined\

Which is confusing because it seems to me it clearly is being defined.

I accidentally replied to the email - haven’t used Google Groups a lot, sorry about that.

I had actually tried this already. When I do I get this error:

`
“msg”: "The task includes an option with an undefined variable. The error was: ‘new_ami_id’ is undefined\

`

Which is confusing because it seems to me it clearly is being defined.

On what line was that error thrown?

I think you should provide the entire playbook and the complete output.

Regards, K.

This is the playbook:

`

  • hosts: webservers
    remote_user: ubuntu
    tasks:

  • name: create an ami
    ec2_ami:
    region: eu-west-2
    instance_id: i-077xxxxxxxxxxx
    name: “{{ inventory_hostname }}-{{ ansible_date_time.iso8601_basic_short }}”
    tags:
    Name: “{{ inventory_hostname }}-{{ ansible_date_time.iso8601_basic_short }}”
    register: ami

  • name: set ami id
    set_fact:
    new_ami_id: “{{ ami.results[0].image_id }}”

  • pause:
    seconds: 60

  • name: copy AMI to a different region
    ec2_ami_copy:
    source_region: eu-west-2
    source_image_id: “{{ new_ami_id }}”
    name: “{{ new_ami_id }}”
    region: eu-west-1
    `

And the full output:

`
ansible-playbook 2.6.4
config file = /etc/ansible/ansible.cfg
configured module search path = [u’/home/ubuntu/.ansible/plugins/modules’, u’/usr/share/ansible/plugins/modules’]
ansible python module location = /usr/lib/python2.7/dist-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 2.7.15rc1 (default, Nov 12 2018, 14:31:15) [GCC 7.3.0]
Using /etc/ansible/ansible.cfg as config file
[WARNING]: Ignoring invalid attribute: new_ami_id

PLAYBOOK: create-ami.new.yml **************************************************************************************************************************************************************************************
1 plays in create-ami.new.yml

PLAY [webservers] *************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
task path: /opt/ansible-scripts/update/create-ami.new.yml:2
ok: [server.mydomain.com]
META: ran handlers

TASK [create an ami] **********************************************************************************************************************************************************************************************
task path: /opt/ansible-scripts/update/create-ami.new.yml:5
changed: [server.mydomain.com] => {“architecture”: “x86_64”, “block_device_mapping”: {}, “changed”: true, “creationDate”: “2018-12-04T16:14:50.000Z”, “description”: “”, “enhanced_networking”: true, “hypervisor”: “xen”, “image_id”: “ami-02867e4b6aec13ee5”, “image_owner_alias”: null, “image_type”: “machine”, “is_public”: false, “kernel_id”: null, “launch_permissions”: , “location”: “541818391026/server.mydomain.com-20181204T161449”, “msg”: “AMI creation operation complete.”, “name”: “server.mydomain.com-20181204T161449”, “ownerId”: “541818391026”, “platform”: null, “product_codes”: , “ramdisk_id”: null, “root_device_name”: null, “root_device_type”: “ebs”, “sriov_net_support”: null, “state”: “pending”, “state_reason”: null, “tags”: {“Name”: “server.mydomain.com-20181204T161449”}, “virtualization_type”: “hvm”}

TASK [set ami id] *************************************************************************************************************************************************************************************************
task path: /opt/ansible-scripts/update/create-ami.new.yml:14
ok: [server.mydomain.com] => {“ansible_facts”: {}, “changed”: false}

TASK [pause] ******************************************************************************************************************************************************************************************************
task path: /opt/ansible-scripts/update/create-ami.new.yml:18
Pausing for 60 seconds
(ctrl+C then ‘C’ = continue early, ctrl+C then ‘A’ = abort)
ok: [server.mydomain.com] => {“changed”: false, “delta”: 60, “echo”: true, “rc”: 0, “start”: “2018-12-04 16:14:51.149347”, “stderr”: “”, “stdout”: “Paused for 60.0 seconds”, “stop”: “2018-12-04 16:15:51.149596”, “user_input”: “”}

TASK [copy AMI to a different region] *****************************************************************************************************************************************************************************
task path: /opt/ansible-scripts/update/create-ami.new.yml:21
fatal: [server.mydomain.com]: FAILED! => {“msg”: “The task includes an option with an undefined variable. The error was: ‘new_ami_id’ is undefined\n\nThe error appears to have been in ‘/opt/ansible-scripts/update/create-ami.new.yml’: line 21, 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: copy AMI to a different region\n ^ here\n”}
to retry, use: --limit @/opt/ansible-scripts/update/create-ami.new.retry

PLAY RECAP ********************************************************************************************************************************************************************************************************
server.mydomain.com : ok=4 changed=1 unreachable=0 failed=1
`

This WARNING is the hint, you indentation of new_ami_id in set_fact is missing two spaces.

The line where you set new_ami_id, immediately below set_fact:, does not appear to be indented correctly. Indent it a few spaces and try again.

Regards, K.

Ah yes, apologies for that. So I’ve corrected that, but getting an undefined variable error.

fatal: [server.mydomain.com]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'results'\n\nThe error appears to have been in '/opt/ansible-scripts/update/create-ami.new.yml': line 14, 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: set ami id\n ^ here\n"}

Read the documentation for ec2_ami:

https://docs.ansible.com/ansible/latest/modules/ec2_ami_module.html#return-values

… or the doco for the particular version of Ansible that you are using.

The section “Return values” describes the structure inside your registered variable “ami”.

It looks to me as if to retrieve the AMI ID, you need to use “{{ ami.image_id }}”.

'dict object' has no attribute 'result' means "there is no thing called 'result' inside the variable you are looking at".

That means you either have the wrong variable (and 'result' is to be found in a different variable) or you have the correct variable, but there is nothing called "result" inside it.

Regards, K.

You were right - I had to change that line to:

`
new_ami_id: “{{ ami.image_id }}”

`

Thanks for the help. I’ve given the documentation a good read, and will keep doing so, but these things can still be hard to figure out.