检查 EC2 实例是否存在并正在运行,然后跳过部署

发布于 2025-01-12 07:24:37 字数 1337 浏览 2 评论 0原文

我正在尝试运行一个调用角色来部署一些 EC2 实例的剧本,一切正常,除了我想在 EC2 实例存在且处于运行状态时设置一个条件以跳过部署我使用以下命令来检索 ec2_infos :

## Check if an instance with same name exist on AWS
- name: Get {{ ec2_name }} infos
  ec2_instance_info:
    region: "us-east-1"
    filters:
      "tag:Name": "{{ ec2_name }}"
      instance-state-name: [ "running"]
  register: ec2_infos

- name: DEBUG
  debug: msg="{{ aws_ec2_infos }}"

在部署阶段,我的情况如下:


- name: "{{ ec2_description }} - {{ ec2_name }}"
  cloudformation:
    stack_name: "some name "
    state: "present"
    region: "{{ aws_region }}"
    template: "PATH/ec2.json"
    template_parameters:
      Name: "{{ ec2_name }}"
      Description: "{{ ec2_description }}"
      KeyName: "{{key_name }}"
      KmsKeyId: "{{ key_id }}"
      GroupSet: "{{ id }}"
      IamInstanceProfile: "{{ name }}"
      Type: "OS"
  **when: ec2_infos.state[0].name != 'running'**

但我收到一条错误消息:

"msg": "The conditional check 'aws_ec2_infos.state[0].name != 'running'' failed. The error was: error while evaluating conditional (aws_ec2_infos.state[0].name != 'running'): 'dict object' has no attribute 

我认为我的情况缺少某些内容,但我找不到确切的内容。非常欢迎任何提示或建议

I am trying to run a playbook that calls a role to deploy some EC2 instances, everything works fine except that I want to put a condition when the EC2 instance exists and in running state to skip the deployment I used the following to retrieve the ec2_infos :

## Check if an instance with same name exist on AWS
- name: Get {{ ec2_name }} infos
  ec2_instance_info:
    region: "us-east-1"
    filters:
      "tag:Name": "{{ ec2_name }}"
      instance-state-name: [ "running"]
  register: ec2_infos

- name: DEBUG
  debug: msg="{{ aws_ec2_infos }}"

and on the Deployment stage my condition is as follows :


- name: "{{ ec2_description }} - {{ ec2_name }}"
  cloudformation:
    stack_name: "some name "
    state: "present"
    region: "{{ aws_region }}"
    template: "PATH/ec2.json"
    template_parameters:
      Name: "{{ ec2_name }}"
      Description: "{{ ec2_description }}"
      KeyName: "{{key_name }}"
      KmsKeyId: "{{ key_id }}"
      GroupSet: "{{ id }}"
      IamInstanceProfile: "{{ name }}"
      Type: "OS"
  **when: ec2_infos.state[0].name != 'running'**

but I get an error that says :

"msg": "The conditional check 'aws_ec2_infos.state[0].name != 'running'' failed. The error was: error while evaluating conditional (aws_ec2_infos.state[0].name != 'running'): 'dict object' has no attribute 

I think I am missing something in my condition but I can't find what exactly. Any tip or advice is more than welcome

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

衣神在巴黎 2025-01-19 07:24:37

正如 @benoit 和 @mdaniel 所说,错误是在我的理解中,条件应该是:

aws_ec2_infos.instances[0].state.name != 'running'

As @benoit and @mdaniel said the error was in my understanding the condition should be :

aws_ec2_infos.instances[0].state.name != 'running'
寂寞清仓 2025-01-19 07:24:37

需要解决的一些额外问题:

  • Ansible 配合 terraform 部署 EC2 实例不是幂等的!它每次都会摧毁并重建你的机器!
  • 机器可能处于除运行之外的有效状态。例如关机。源中的完整列表。警告;不保证 AWS 会保持该列表相同。检查来源!
  • 如果机器被破坏并重新创建,主机密钥将会更改。特别感谢上面的帖子提供了解决方案。如果您处于经常重新部署计算机的环境中,则更容易忽略主机密钥检查。
  • terraform 之后,机器需要一些时间来启动。如果部署后没有立即进行连接检查,您的 ansible 脚本将会失败!

playbook.yml

---
- name: Deploy My Server
  hosts: MyServerName
  gather_facts: false

  tasks:

    # Source of instance-state-name values:
    # https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html
    - name: Check existence of server
      ec2_instance_info:
        region: "us-east-1"
        filters:
          "tag:Name": "MyServerName"
          instance-state-name: ['pending','running','shutting-down','stopping',
            'stopped']
      delegate_to: localhost
      register: server_info

    - name: Deploy EC2 machine
      community.general.terraform:
        project_path: terraform_code/
        state: present
      delegate_to: localhost
      when: server_info.instances | length == 0

    - name: Wait 5 minutes, but only start checking after 30 seconds
      ansible.builtin.wait_for_connection:
        delay: 30
        timeout: 300
      when: server_info.instances | length == 0

- name: Reconnect to server with gather_facts
  hosts: MyServerName
  tasks:
    - name: Do stuff...

库存.yml

MyServerName:
  hosts:
    192.168.0.1:
  vars:
    ansible_ssh_common_args:
      "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"

Some extra issues to resolve:

  • Ansible with terraform to deploy EC2 instances is not idempotent! It will destroy and recreate your machine every time!
  • The machine might be in valid states other then running. E.g. shutting-down. Full list in the source. WARNING; no guarantee AWS will keep the list the same. Check the source!
  • Host keys will change if a machine is destroyed and re-created. Special thanks to the post above providing a solution to this. If you're in an environment where you're re-deploying machines often, it's easier to ignore host key checks.
  • Immediately after terraform, the machine needs some time to bootup. Your ansible script will fail without some connection check immediately after deploy!

playbook.yml

---
- name: Deploy My Server
  hosts: MyServerName
  gather_facts: false

  tasks:

    # Source of instance-state-name values:
    # https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html
    - name: Check existence of server
      ec2_instance_info:
        region: "us-east-1"
        filters:
          "tag:Name": "MyServerName"
          instance-state-name: ['pending','running','shutting-down','stopping',
            'stopped']
      delegate_to: localhost
      register: server_info

    - name: Deploy EC2 machine
      community.general.terraform:
        project_path: terraform_code/
        state: present
      delegate_to: localhost
      when: server_info.instances | length == 0

    - name: Wait 5 minutes, but only start checking after 30 seconds
      ansible.builtin.wait_for_connection:
        delay: 30
        timeout: 300
      when: server_info.instances | length == 0

- name: Reconnect to server with gather_facts
  hosts: MyServerName
  tasks:
    - name: Do stuff...

inventory.yml

MyServerName:
  hosts:
    192.168.0.1:
  vars:
    ansible_ssh_common_args:
      "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文