Ansible 动态清单,带有静态组和动态子项
Ansible Dynamic inventory with static group with dynamic children
我相信很多每天使用 Terraform 和 Ansible 或只使用 Ansible 的人一定遇到过这个问题。
一些背景:
我使用 Terraform 在 AWS 上创建我的基础设施,并使用 Ansible 配置我的机器。我的清单文件包含带有一些变量的硬编码 public IP 地址。根据业务需要,我经常创建和销毁我的机器。
我的问题:
我不想在每次销毁和创建我的实例时使用新的 public IP 地址更新我的清单文件。所以我的基本要求是——每次我销毁我的机器时,我应该能够 运行 我的 Terraform 脚本重新创建机器,当我 运行 我的 Ansible 剧本时,Ansible 应该能够选择正确的目标机器和 运行 剧本。我需要知道我需要在库存文件中描述什么才能实现这种自动化。清单文件中的域名 (www.fooexample.com) 和静态 public IP 地址在我的情况下不是一个选项?我见过用它来做的脚本,它看起来像一个主机名 (webserver1)
有些论坛讨论使用 ec2.py 选项,但 ec2.py 正在获取与该帐户关联的所有 public IP 地址,但我只想针对某些机器正如您所想象的那样,并非所有这些都与我的剧本有关。
如有任何帮助,我们将不胜感激。
提前致谢
我在 GCP 中做了类似的事情,但这个概念应该适用于 AWS。
从 Ansible 2.7 开始,有一个新的清单插件架构和一些清单插件来替换动态清单脚本(例如 ec2.py
和 gcp.py
)。 AWS 插件文档位于 https://docs.ansible.com/ansible/2.9/plugins/inventory/aws_ec2.html.
首先,您需要在 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_groups
和 compose
部分。这将为您提供 public IP 地址作为清单中要连接的主机和您可以使用 -l
或 --limit
.
限制的组
考虑到你在 us-east-1
中有一些实例被标记为 Service = Web
你可以像这样定位它们:
ansible -i aws_ec2.yaml -m ping -l tag_Service_Web
这将只针对那些在其 public IP 地址上标记的主机。您所做的任何动态缩放(例如增加该资源在 Terraform 中的计数)都将在下一个 运行.
上由库存插件获取
您也可以在剧本中使用该标签。如果您有一个始终针对这些主机的剧本,您可以在剧本中设置 hosts: tag_Service_Web
。
奖金:
我一直在试验 Ansible Pull model that automates some of this bootstrapping. The idea is to combine cloud-init 和一个特殊的脚本来自动 bootstrap 该主机的剧本。
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 或其他启动时配置服务执行 bootstrapping 密钥之类的操作来使其适应 AWS。我发现 ansible-pull
在 playbook 只需要一两分钟到 运行 并且不依赖于外部清单(比如对其他组的引用,例如收集 IP 地址)时效果很好。
我相信很多每天使用 Terraform 和 Ansible 或只使用 Ansible 的人一定遇到过这个问题。
一些背景:
我使用 Terraform 在 AWS 上创建我的基础设施,并使用 Ansible 配置我的机器。我的清单文件包含带有一些变量的硬编码 public IP 地址。根据业务需要,我经常创建和销毁我的机器。
我的问题:
我不想在每次销毁和创建我的实例时使用新的 public IP 地址更新我的清单文件。所以我的基本要求是——每次我销毁我的机器时,我应该能够 运行 我的 Terraform 脚本重新创建机器,当我 运行 我的 Ansible 剧本时,Ansible 应该能够选择正确的目标机器和 运行 剧本。我需要知道我需要在库存文件中描述什么才能实现这种自动化。清单文件中的域名 (www.fooexample.com) 和静态 public IP 地址在我的情况下不是一个选项?我见过用它来做的脚本,它看起来像一个主机名 (webserver1)
有些论坛讨论使用 ec2.py 选项,但 ec2.py 正在获取与该帐户关联的所有 public IP 地址,但我只想针对某些机器正如您所想象的那样,并非所有这些都与我的剧本有关。
如有任何帮助,我们将不胜感激。
提前致谢
我在 GCP 中做了类似的事情,但这个概念应该适用于 AWS。
从 Ansible 2.7 开始,有一个新的清单插件架构和一些清单插件来替换动态清单脚本(例如 ec2.py
和 gcp.py
)。 AWS 插件文档位于 https://docs.ansible.com/ansible/2.9/plugins/inventory/aws_ec2.html.
首先,您需要在 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_groups
和 compose
部分。这将为您提供 public IP 地址作为清单中要连接的主机和您可以使用 -l
或 --limit
.
考虑到你在 us-east-1
中有一些实例被标记为 Service = Web
你可以像这样定位它们:
ansible -i aws_ec2.yaml -m ping -l tag_Service_Web
这将只针对那些在其 public IP 地址上标记的主机。您所做的任何动态缩放(例如增加该资源在 Terraform 中的计数)都将在下一个 运行.
上由库存插件获取您也可以在剧本中使用该标签。如果您有一个始终针对这些主机的剧本,您可以在剧本中设置 hosts: tag_Service_Web
。
奖金:
我一直在试验 Ansible Pull model that automates some of this bootstrapping. The idea is to combine cloud-init 和一个特殊的脚本来自动 bootstrap 该主机的剧本。
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 或其他启动时配置服务执行 bootstrapping 密钥之类的操作来使其适应 AWS。我发现 ansible-pull
在 playbook 只需要一两分钟到 运行 并且不依赖于外部清单(比如对其他组的引用,例如收集 IP 地址)时效果很好。