使用ansible启动EC2实例时如何等待user_data脚本运行?

Gui*_*sta 5 amazon-ec2 ansible

我正在使用 Ansible 启动和配置当前基于未安装 Python 的 AMI (ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-20161020 (ami-40d28157)) 中的 EC2 实例从一开始。

由于大多数 ansible 模块需要在远程计算机上使用 python 才能工作,因此我尝试使用user_data脚本在启动实例上安装 python,而不是选择使用不同的 AMI 。

有点工作(Python 已正确安装),但 ansible ec2任务在 user_data 脚本完成运行之前返回,因此接下来的任务(实际配置实例的任务)失败并出现错误'/bin/sh: 1: /usr/bin/python: not found\r\n'

由于没有 python,我什至无法在远程主机上运行大多数任务,因此我无法简单地检查/usr/bin/python标记文件是否存在,或者检查系统日志输出等。

我考虑过nc -l $SOME_PORT在 user_data 脚本末尾添加 a 并使用wait_for模块检查它,但这对我来说听起来太麻烦了。

有没有办法使用ec2模块启动实例,以便它等待 user_data 脚本完成运行?

以供参考:

与我正在使用的类似的剧本:

- name: Create the EC2 instance
  hosts: localhost
  gather_facts: false
  vars: 
    name: myinstance
    ami: ami-40d28157
    #Other vars ommited for brevity
  tasks:
    - name: Launch Instance
      ec2:
        key_name: "{{ keypair }}"
        group: "{{ security_group }}"
        instance_type: "{{ instance_type }}"
        image: "{{ ami }}"
        user_data: "{{ lookup('file', 'user_data.sh') }}"
        wait: true
        region: "{{ region }}"
        vpc_subnet_id: "{{ subnet }}"
        assign_public_ip: no
        zone: "{{ zone }}"
        instance_tags: "{{ tag_map }}"
        exact_count: 1
        count_tag:
          Name: "{{ name }}"
      register: ec2

    - name: Add new Instance to host group
      add_host: name={{ item.private_ip }} groups={{ name }}
      with_items: "{{ ec2.instances }}"

    - name: Wait for SSH to come up
      wait_for: host={{ item.private_ip }} port=22 delay=60 timeout=320 state=started
      with_items: "{{ ec2.instances }}"

- name: Configure instance(s)
  hosts: myinstance
  tasks:
    - name: Example task
      command: touch a_file
Run Code Online (Sandbox Code Playgroud)

user_data.sh脚本:

#!/bin/bash
set -e -x
export DEBIAN_FRONTEND=noninteractive
sudo locale-gen pt_BR.UTF-8
sudo apt-get update && apt-get upgrade -y
sudo apt-get install -y python-minimal
Run Code Online (Sandbox Code Playgroud)

Ada*_*nek 11

事实证明你可以使用cloud-init命令来实现这一点,即:

cloud-init status --wait
Run Code Online (Sandbox Code Playgroud)

因此,您应该将以下片段添加到您的剧本中:

- name: Wait for cloud-init / user-data to finish
  command: cloud-init status --wait
  changed_when: false
Run Code Online (Sandbox Code Playgroud)

与第一个答案相比,它看起来更干净一些。


Kon*_*rov 6

以下是您的问题“使用 ansible 启动 EC2 实例时如何等待用户数据脚本运行?”的答案。:

- raw: test -f /var/lib/cloud/instance/boot-finished
  retries: 20
  register: cmd_res
  changed_when: false
  until: cmd_res | success
Run Code Online (Sandbox Code Playgroud)

boot-finished这将通过 ssh 连接并在存在时成功,这是cloud-init在主机上的模块完成所有模块(包括 user_data 脚本)后创建的。

但我建议创建预装 Python 的 AMI,或者使用rawAnsiblescript模块来检查/安装 Python(这些模块不需要 Python)。

  • 请注意,对于 ansible >= 2.8,此解决方案会给出弃用警告。[弃用警告]:不推荐使用测试作为过滤器。不要使用“结果|成功”,而是使用“结果就是成功”。 (2认同)