ansible 模块 amazon.aws.ec2_instance - 无法获取公共 IP

mli*_*ist 3 module amazon-ec2 ansible

我使用“旧”EC2 Ansible 模块创建了以下剧本:

---
- name: Create Ec2 instances
  hosts: localhost
  become: False
  # import the secret file
  vars_files:
    - secrets.yml
  gather_facts: false
  tasks:

  # Block is a Group of Tasks combined together
  - name: Get Info Block
    block:
      - name: Get Running instance Info

        ec2_instance_info:
        register: ec2info

      - name: Print info
        debug: var="ec2info.instances"

  - name: Create EC2 Block
    block:

      - name: Launch ec2 instances
        tags: create_ec2
        ec2:
          region: eu-west-1
          key_name: ec2-tutorial
          group: launch-wizard-1
          instance_type: t2.micro
          image: ami-04dd4500af104442f
          wait: yes
          wait_timeout: 500
          count: 1
          instance_tags:
            name: appservers
            os: ubuntu
          monitoring: no
          vpc_subnet_id: subnet-049055a2c1633c0eb
          assign_public_ip: yes
          aws_access_key: XXXX
          aws_secret_key: YYYYYYY
        register: ec2
        delegate_to: localhost

      - name : Add instance to host group
        add_host:
          hostname: "{{ item.public_ip }}"
          groupname: launched
        loop: "{{ ec2.instances }}"

      - name: Wait for SSH to come up
        local_action:
          module: wait_for
          host: "{{ item.public_ip }}"
          port: 22
          delay: 10
          timeout: 120
        loop: "{{ ec2.instances }}"
    # By specifying never on the tag of this block,
    # I let this block to run only when explicitely being called
    tags: ['never', 'ec2-create']
Run Code Online (Sandbox Code Playgroud)

它工作正常,我能够创建 EC2 实例并测试连接并检索其公共 IP。

问题是 EC2 已被弃用,因此;ec2_instance我使用不返回公共 IP 的新模块重写了相同的剧本。
由于我无法测试连接,因此我暂时放置了一个- meta: end_play,以便我可以部署实例。
这是新的剧本

---
- name: Create Ec2 instances
  hosts: localhost
  become: False
  # import the secret file
  vars_files:
    - secrets.yml
  gather_facts: false
  tasks:

  # Block is a Group of Tasks combined together
  - name: Get Info Block
    block:
      - name: Get Running instance Info

        ec2_instance_info:
        register: ec2info

      - name: Print info
        debug: var="ec2info.instances"

    # By specifying always on the tag,
    #     # I let this block to run all the time by module_default
    #         # this is for security to net create ec2 instances accidentally
    tags: ['always', 'getinfoonly']

  - name: Create EC2 Block
    block:

      - name: Launch ec2 instances
        tags: create_ec2
        ec2_instance:
          name: "Test new Ansible ec2 module"
          region: eu-west-1
          #Availability zone is mutually excluded with vpc_subnet_id
          #availability_zone: eu-west-1c
          #key_name: ec2-tutorial
          key_name: testec2key
          security_group: launch-wizard-1
          instance_type: t2.micro
          image_id: ami-04dd4500af104442f
          wait: yes
          volumes:
            - device_name: /dev/sdb
              ebs:
                volume_size: 8
                delete_on_termination: true
            #- device_name: /dev/sdb
            #  volume_type: gp2
            #  volume_size: 5
            #  delete_on_termination: true
          wait_timeout: 500
          # count not available is this new module
          #count: 1
          tags:
            name: "Test"
            os: AwsAmi
          #vpc_subnet_id: subnet-049055a2c1633c0eb
          vpc_subnet_id: subnet-08a394b8718bbff45
          network:
            assign_public_ip: true
          #termination_protection: yes
          #aws_access_key: XXXXXXX
          #aws_secret_key: YYYYYYYYYYY
        register: ec2
        delegate_to: localhost

      #- meta: end_play

      - name: Add instance to host group
        add_host:
          hostname: "{{ item.public_ip }}"
          groupname: launched
        loop: "{{ ec2.instances }}"
               
      - name: Wait for SSH to come up
        local_action:
          module: wait_for
          host: "{{ item.public }}"
          port: 22
          delay: 10
          timeout: 120
        loop: "{{ ec2.instances }}"
    # By specifying never on the tag of this block,
    # I let this block to run only when explicitely being called
    tags: ['never', 'ec2-create']
Run Code Online (Sandbox Code Playgroud)

这是我运行剧本时遇到的错误,评论- meta: end_play(这使得剧本继续):

ansible-playbook aws-ec2-creationtst3.yml --connection=local --tags=ec2-create -e "ansible_python_interpreter=/home/marcoreale/aws-venv/bin/python3" --ask-vault-pass -vvvv

TASK [Add instance to host group] **************************************************************************************
task path: /home/xxx/aws-venv/playbook/aws-ec2-create/aws-ec2-creationtst3.yml:70
fatal: [localhost]: FAILED! => {
   "msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'public_ip'\n\nThe error appears to be in '/home/marcoreale/aws-venv/playbook/aws-ec2-create/aws-ec2-creationtst3.yml': line 70, column 9, 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 instance to host group\n        ^ here\n"
}
Run Code Online (Sandbox Code Playgroud)

错误

注意:替换item.public_ipitem.private_ip有效,但我需要使用公共 IP 测试连接。
您有什么建议吗?我应该如何更改我的剧本以使用公共 IP 测试连接?

Cha*_*son 5

您想要state: running在 ec2_instance 调用中进行设置。基本上发生的情况是,您只能等待,直到它达到定义的状态,并且默认状态不会等待分配 public_ip。