It's even stranger than that (until you realize what's going on).
Rather than commenting out the "ansible_ssh_user:" line, just misspell the
variable, like "ansible_ssh_userx". It'll work then, too — but with the
wrong user of course.
What you're running into is a combination of things: set_fact, delegate_to,
and the bit you didn't show, which is your playbook's "hosts:" line and/or
your command's "--limit" specification. Also the "special variable"
function of the "ansible_ssh_user" variable itself. Maybe throw in lazy
variable template evaluation for good measure.
The error message is correct but incomplete, in that "aws_region" is
undefined. What the message leaves out is "… in the context of the
delegation host 'ec2.instances.0.network_interfaces.0.private_ip_address'".
You set the task variable "ansible_ssh_user" to a template. By lazy
template evaluation, that template isn't evaluated until the variable is
used, which is at the point of connection. So it's evaluated in the context
of a host *which has no set_fact-derived variables defined*:
'ec2.instances.0.network_interfaces.0.private_ip_address'. Only your play
hosts will have set_fact-derived variables.
Assuming your hosts line is something like "hosts: localhost", then you can
work around it by changing your variable definition to
ansible_ssh_user: "{{ amis[*hostvars['localhost'].*aws_region][
*hostvars['localhost'].*os_version].user }}"
I'm reasonably sure (but could be wrong) that the "amis" dict is defined,
because it isn't a host variable. That's different from set_fact-derived
variables which are both host-specific and template resolved at their
creation.
Let us know if this resolves your issue.
--
Todd
On Saturday, January 13, 2024 at 9:40:57 AM UTC-5 ricardo barbosa wrote:
> Hello guys
>
> I created the following structure:
>
> ```
> amis:
> us-east-1:
> amazonlinux:
> owner_id: "137112412989"
> x86_64: "ami-01bc990364452ab3e"
> arm64: "ami-0900a8f768a21540a"
> user: "ec2-user"
> ubuntu:
> owner_id: "099720109477"
> x86_64: "ami-0fc5d935ebf8bc3bc" # Ubuntu 22
> arm64: "ami-016485166ec7fa705" #
> user: "ubuntu"
> ```
>
> and I have a json file that I fill in to raise an ec2 instance:
>
> ```json
> {
> "aws_region":"us-east-1",
> "architecture":"arm64",
> "os_version":"ubuntu",
> "instance_name":"test6",
> "domain":"example.corp",
> "subnet":"SUBNET-PUB-A",
> "instance_type":"t4g.micro",
> "security_groups": [ "sg-xxxxxx", "sg-yyyyyyyy"],
> "aws_role":"default-role",
> "root_volume_size":20,
> "ebs_swap_size": 4,
> "keyname": "ssh-key",
> "ebs_type": "gp3",
> "backup": "no",
> "boxenv":"DEV"
> }
> ```
>
> And I read this json and create the variables with the tasks:
>
> ```
> - name: Read json configuration
> shell: cat config-ec2-launch.json
> register: result
>
> - name: save the Json data to a Variable as a Fact
> set_fact:
> jsondata: "{{ result.stdout | from_json }}"
>
> - name: Variable | Get aws_region variable
> set_fact:
> aws_region: "{{ jsondata | json_query(jmesquery) }}"
> vars:
> jmesquery: 'aws_region'
>
> - name: Variable | Get architecture variable
> set_fact:
> architecture: "{{ jsondata | json_query(jmesquery) }}"
> vars:
> jmesquery: 'architecture'
>
> - name: Variable | Get os_version variable
> set_fact:
> os_version: "{{ jsondata | json_query(jmesquery) }}"
> vars:
> jmesquery: 'os_version'
> ```
>
> and created the tasks right away:
>
> ```
> - name: AWS Ec2 Instance | Create the EC2 instance
> ec2_instance:
> state: started # started state=running + waits for EC2 status
> checks to report OK if wait=true
> image_id: "{{ newest_ami }}"
> name: "{{ instance_name }}"
> detailed_monitoring: false
> metadata_options:
> http_tokens: required
> instance_type: "{{ instance_type }}"
> region: "{{ aws_region }}"
> vpc_subnet_id: "{{ subnet_facts.subnets.0.id }}"
> instance_initiated_shutdown_behavior: stop
> instance_role: "{{ aws_roles[aws_role] }}"
> volumes:
> - device_name: "{{ name_device_root_ami.images.0.root_device_name
> }}"
> ebs:
> volume_type: gp3
> volume_size: "{{ root_volume_size }}"
> delete_on_termination: true
> security_groups: "{{ security_groups }}"
> tags:
> Name: "{{ instance_name }}"
> Domain: "{{ domain }}"
> Backup: "{{ backup }}"
> BOXENV: "{{ boxenv }}"
> key_name: "{{ aws_key_names[keyname] }}"
> wait: yes
> register: ec2
>
> - name: AWS Ec2 ebs | Add volume to swap
> amazon.aws.ec2_vol:
> instance: "{{ ec2.instances[0].instance_id }}"
> volume_size: "{{ ebs_swap_size }}"
> volume_type: "{{ ebs_type }}"
> delete_on_termination: True
> device_name: "/dev/sdf"
> region: '{{ aws_region }}'
> tags:
> Name: "{{ instance_name }}:swap"
> BOXENV: "{{ boxenv }}"
>
>
> - name: Swap | List all devices on {{ instance_name }}
> vars:
> ansible_ssh_user: "{{ amis[ aws_region ][ os_version ].user }}"
> ansible.builtin.shell: echo "{{ aws_region }} {{
> ec2.instances.0.network_interfaces.0.private_ip_address }}"
> register: devices_host
> delegate_to: "{{
> ec2.instances.0.network_interfaces.0.private_ip_address }}"
> args:
> executable: /bin/bash
> ```
>
> But when I run it, it displays the error below
>
> ```
> FAILED! => {"msg": "'aws_region' is undefined"}
> ```
>
> If I comment the line `ansible_ssh_user: "{{ amis[ aws_region ][
> os_version ].user }}"` it displays the contents of the aws_region variable.
> Any
> idea where I'm going wrong?
>
> Thanks
>
>
>
--
You received this message because you are subscribed to the Google Groups
"Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/ansible-project/679a3397-c893-4b88-be21-7faa3caeb2fen%40googlegroups.com.