Amazon web services 具有静态组和动态子组的Ansible动态量表

Amazon web services 具有静态组和动态子组的Ansible动态量表,amazon-web-services,dynamic,ansible,inventory,Amazon Web Services,Dynamic,Ansible,Inventory,我相信很多每天使用Terraform和Ansible或只是Ansible的人一定会遇到这个问题 一些背景: 我使用Terraform在AWS上创建我的基础设施,并使用Ansible配置我的机器。我的清单文件包含带有一些变量的硬编码公共ip地址。由于业务需要,我经常创建和销毁我的机器 我的问题: 我不想每次销毁和创建实例时都用新的公共IP地址更新清单文件。所以我的基本要求是——每次我销毁我的机器时,我都应该能够运行我的Terraform脚本来重新创建机器,当我运行我的Ansible Playboo

我相信很多每天使用Terraform和Ansible或只是Ansible的人一定会遇到这个问题

一些背景:

我使用Terraform在AWS上创建我的基础设施,并使用Ansible配置我的机器。我的清单文件包含带有一些变量的硬编码公共ip地址。由于业务需要,我经常创建和销毁我的机器

我的问题:

我不想每次销毁和创建实例时都用新的公共IP地址更新清单文件。所以我的基本要求是——每次我销毁我的机器时,我都应该能够运行我的Terraform脚本来重新创建机器,当我运行我的Ansible Playbook时,Ansible应该能够选择正确的目标机器并运行Playbook。我需要知道我需要在我的库存文件中描述什么才能实现自动化。在我的情况下,清单文件中的域名(www.fooexample.com)和静态公共IP地址不是一个选项吗?我见过使用类似主机名的脚本(webserver1)

有一些论坛讨论使用ec2.py选项,但ec2.py正在获取与该帐户相关的所有公共ip地址,但我只想针对您可以想象的一些机器,而不是我的playbook中的所有机器

任何有关这方面的帮助都将不胜感激


提前感谢

我在GCP中做了类似的事情,但这个概念应该适用于AWS

从Ansible 2.7开始,有一个新的清单插件体系结构和一些清单插件来取代动态清单脚本(如
ec2.py
gcp.py
)。AWS插件文档位于

首先,需要标记要在AWS中定位的主机组。您应该能够使用Terraform(例如
Service=Web
)处理此问题

接下来,通过添加以下内容启用
ansible.cfg
中的
aws_ec2
插件:

[inventory]
enable_plugins = aws_ec2
现在,改用新插件而不是
ec2.py
。这意味着根据文档创建一个
aws_ec2.yaml
文件。例如:

plugin: aws_ec2
regions:
  - us-east-1
keyed_groups:
  - prefix: tag
    key: tags
# Set individual variables with compose
compose:
  ansible_host: public_ip_address
这里的关键部分是
keyed_组
compose
部分。这将为您提供公共IP地址,作为要连接的主机,您可以使用
-l
--limit
将其限制在资源清册和组中

考虑到您在
us-east-1
中有一些实例标记为
Service=Web
,您可以将它们作为目标:

ansible -i aws_ec2.yaml -m ping -l tag_Service_Web
这将只针对其公共IP地址上的标记主机。您所做的任何动态缩放(例如在Terraform中增加该资源的数量)都将在下一次运行时由inventory插件获取

也可以在剧本中使用标记。如果您有一个始终针对这些主机的剧本,您可以在剧本中设置
hosts:tag\u Service\u Web

奖金:

我一直在用一个模型进行实验,该模型可以自动执行一些引导过程。这个想法是结合一个特殊的脚本来自动引导该主机的剧本

cloud init
启动的示例脚本:

#!/bin/bash

set -euo pipefail

lock_files=(
    /var/lib/dpkg/lock
    /var/lib/apt/lists/lock
    /var/lib/dpkg/lock-frontend
    /var/cache/apt/archives/lock
    /var/lib/apt/daily_lock
)

export ANSIBLE_HOST_PATTERN_MISMATCH="ignore"
export PATH="/tmp/ansible-venv/bin:$PATH"

for file in "${lock_files[@]}"; do
    while fuser "$file" >/dev/null 2>&1; do
        echo "Waiting for lock $file to be available..."
        sleep 5
    done
done

apt-get update -qy
apt-get install --no-install-recommends -qy virtualenv python-virtualenv python-nacl python-wheel python-bcrypt

virtualenv -p /usr/bin/python --system-site-packages /tmp/ansible-venv
pip install ansible==2.7.10 apache-libcloud==2.3.0 jmespath==0.9.3

ansible-pull myplaybook.yaml \
    -U git@github.com:myorg/infrastructure.git \
    -i gcp_compute.yaml \
    --private-key /tmp/ansible-keys/infrastructure_ssh_deploy_key \
    --vault-password-file /tmp/ansible-keys/vault \
    -d /tmp/ansible-infrastructure \
    --accept-host-key

这个脚本与我的实际脚本相比有点简化(省略了一些特定于域的身份验证和密钥提供的内容)。但您可以通过从S3或KMS或其他启动时配置服务中引导密钥之类的操作将其适应AWS。我发现
ansible pull
运行playbook只需一两分钟,并且不依赖于外部资源清册(如对其他组的引用,如收集IP地址)。

解决方案是动态资源清册。你看了那张照片了吗?你可以根据一个实例标记来定位一个自动为你创建的组。谢谢,伙计。这回答了我的问题。但是在命令“ansible-i aws_ec2.yaml-m ping-l tag_Service_Web”中,-l参数对我不起作用,相反,它对ansible-i aws_ec2.yaml-m ping tag_Service_Web起作用。不知道为什么!你说得对<代码>-l仅用于
ansible playbook
。我的错误。