首页 > 解决方案 > Ansible from_json 过滤不返回输出

问题描述

我正在使用 AWS CLI 在我的剧本中创建一个动态 EC2 清单列表。我正在使用from_jsonjinja2 过滤器来格式化标准输出。然后我需要获取所有私有 IP 地址来创建主机列表。但是,我注意到当我尝试创建主机组时我的代码没有返回任何数据,因此出现以下错误:

{ "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'ansible.vars.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'PrivateIpAddress'\n\nThe error appears to have been in '/var/lib/awx/projects/_668__symantec_cloud_workload_protection/main.yml': line 65, 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: Add instances to ansible group\n ^ here\n", "failed": true }

我怎样才能简单地提取PrivateIpAddress价值?

Code:

---

- hosts: localhost
  gather_facts: False
  tasks:
    - name: assume role
      sts_assume_role:
        role_arn: "arn:aws:iam::{{ account_num }}:role/my_role"
        role_session_name: "Session"
        region: "{{ region }}"
      register: assumed_role

- hosts: localhost
  tasks:
    - name: Get instance details for environment
      command: aws ec2 describe-instances --region "{{ region }}" --filters Name=vpc-id,Values="{{ vpc_id }}" Name=tag:environment,Values="{{ env }}"
      register: instances_result
      changed_when: false

    - name: Set instances fact
      set_fact:
        instances_fact: "{{ instances_result.stdout|from_json }}"

    - debug: var=instances_fact verbosity=2

    - name: Add instances to ansible group
      add_host: name={{ item.PrivateIpAddress }} groups=vpc_instances
      with_items: "{{ instances_fact }}"

    - name: Print ansible host groups
      debug: var=groups verbosity=2

  environment:
    AWS_ACCESS_KEY_ID: "{{ assumed_role.sts_creds.access_key }}"
    AWS_SECRET_ACCESS_KEY: "{{ assumed_role.sts_creds.secret_key }}"
    AWS_SESSION_TOKEN: "{{ assumed_role.sts_creds.session_token }}"

- hosts: vpc_instances
  become: yes
  roles:
    - { role: foo_bar, yum_update: False }

我注意到该debug任务被跳过,因为没有返回数据:

TASK [debug] *******************************************************************11:30:33 23 skipping: [localhost] NO JSON data returned by the module

这是上面任务的json输出:set_fact

{
    "invocation": {
        "module_name": "set_fact",
        "module_args": ""
    },
    "changed": false,
    "ansible_facts": {
        "instances_fact": {
            "Reservations": [{
                    "Instances": [{
                        "Monitoring": {
                            "State": "disabled"
                        },
                        "PublicDnsName": "ec2-xxxxxx",
                        "State": {
                            "Code": 16,
                            "Name": "running"
                        },
                        "EbsOptimized": false,
                        "LaunchTime": "xxxxxxx",
                        "PublicIpAddress": "x.x.x.x",
                        "PrivateIpAddress": "x.x.x.x",
                        "ProductCodes": [{
                            "ProductCodeId": "axxxxxxxxxxxxxx",
                            "ProductCodeType": "marketplace"
                        }],
                        "VpcId": "vpc-xxxxxx",
                        "StateTransitionReason": "",
                        "SecurityGroups": [{
                             "GroupName": "va-xxxxxx",
                            "GroupId": "sg-xxxxxx"
                        }],
                        "ClientToken": "",
                        "SubnetId": "subnet-xxxxxxxx",
                        "InstanceType": "t2.micro",
                        "NetworkInterfaces": [{
                            "Status": "in-use",
                            "PrivateIpAddresses": [{
                                "PrivateDnsName": "ip-xxxxxxxxxxxx",
                                "PrivateIpAddress": "x.x.x.x",
                                "Primary": true,
                                "Association": {
                                    "PublicIp": "x.x.x.x",
                                    "PublicDnsName": "ec2-xxxxxxx",
                                    "IpOwnerId": "amazon"
                                }
                            }],
                             "Attachment": {
                                "Status": "attached"
                            },
                            "Groups": [{
                                "GroupName": "va-xxxxxxxx",
                                "GroupId": "sg-xxxxxxx"
                            }],
                            "Ipv6Addresses": [],
                            "OwnerId": "xxxxxxxx",
                            "PrivateIpAddress": "x.x.x.x",
                            "SubnetId": "subnet-xxxxxxxxx",
                            "Association": {
                                "PublicIp": "x.x.x.x",
                                "PublicDnsName": "exxxxxxxxxx",
                                "IpOwnerId": "amazon"
                            }
                        }],
                        "SourceDestCheck": true,
                        "Placement": {
                            "GroupName": "",
                            "Tenancy": "default",
                            "AvailabilityZone": "us-east-1a"
                        },
                        "Hypervisor": "xen",
                        "BlockDeviceMappings": [{
                            "DeviceName": "/dev/sda1",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-xxxxxxxxx",
                                "AttachTime": "2xxxxxxxxxxxx"
                            }
                        }],
                        "Architecture": "x86_64",
                        "RootDeviceType": "ebs",
                        "RootDeviceName": "/dev/sda1",
                        "VirtualizationType": "hvm",
                        "Tags": [{
                                "Value": "cloud_platform",
                                "Key": "application"
                            }

                        ],
                        "AmiLaunchIndex": 0
                    }],
                    "ReservationId": "r-xxxxxxxxxx",
                    "Groups": [],
                    "OwnerId": "xxxxx"
                }

            ]
        }
    },
    "_ansible_no_log": false
}

标签: jsonamazon-web-servicesansibleansible-2.x

解决方案


您将变量 instance_fact 注册为 json 字符串,我相信如果您打算迭代它以添加主机,您只想注册实例列表。我也会使用模块 ec2_instance_facts 来收集您的详细信息,这样您就不必担心解析 json 等。

尝试像这样注册 .instances :

- hosts: localhost
  tasks:
    - name: Get instance details for environment
      ec2_instance_facts:
        filters:
          "tag:environment": "{{ env }}"
        region: "{{ region }}"
      register: instance_result

    - name: Set instances fact
      set_fact:
        instances_fact: "{{ instances_result.instances }}"
                              /\              /\    
    - debug: var=instances_fact verbosity=2

    - name: Add instances to ansible group
      add_host: name={{ item.PrivateIpAddress }} groups=vpc_instances
      with_items: "{{ instances_fact }}"

推荐阅读