显示主机的自定义名称
Displaying a custom name for a host
我有一本用于处理 EC2 实例的 Ansible 剧本。我正在使用动态清单 (ec2.py) 来获取我想要使用的实例组 (hosts: tag_Service_Foo
)。当我 运行 它时,它会产生如下输出:
GATHERING FACTS ***************************************************************
ok: [54.149.9.198]
ok: [52.11.22.29]
ok: [52.11.0.3]
但是,我可以从 Amazon 获取特定实例的 "Name" 标签(我这样做并将其存储在一个变量中以供剧本的几个部分使用)。
有没有办法让 Ansible 在显示进度时使用这个字符串作为主机名?我希望看到更具描述性的内容(因为我没有记住 IP):
GATHERING FACTS ***************************************************************
ok: [main-server]
ok: [extra-server]
ok: [my-cool-server]
ec2.py
库存脚本的输出看起来像这样(t运行cated;它很长)。
{
"_meta": {
"hostvars": {
"54.149.9.198": {
"ec2__in_monitoring_element": false,
"ec2_ami_launch_index": "0",
"ec2_architecture": "x86_64",
"ec2_client_token": "xxx",
"ec2_dns_name": "xxx",
"ec2_ebs_optimized": false,
"ec2_eventsSet": "",
"ec2_group_name": "",
"ec2_hypervisor": "xen",
"ec2_id": "i-xxx",
"ec2_image_id": "ami-xxx",
"ec2_instance_type": "xxx",
"ec2_ip_address": "xxx",
"ec2_item": "",
"ec2_kernel": "",
"ec2_key_name": "xxx",
"ec2_launch_time": "xxx",
"ec2_monitored": xxx,
"ec2_monitoring": "",
"ec2_monitoring_state": "xxx",
"ec2_persistent": false,
"ec2_placement": "xxx",
"ec2_platform": "",
"ec2_previous_state": "",
"ec2_previous_state_code": 0,
"ec2_private_dns_name": "xxx",
"ec2_private_ip_address": "xxx",
"ec2_public_dns_name": "xxx",
"ec2_ramdisk": "",
"ec2_reason": "",
"ec2_region": "xxx",
"ec2_requester_id": "",
"ec2_root_device_name": "/dev/xvda",
"ec2_root_device_type": "ebs",
"ec2_security_group_ids": "xxx",
"ec2_security_group_names": "xxx",
"ec2_sourceDestCheck": "true",
"ec2_spot_instance_request_id": "",
"ec2_state": "running",
"ec2_state_code": 16,
"ec2_state_reason": "",
"ec2_subnet_id": "subnet-xxx",
"ec2_tag_Name": "main-server",
"ec2_tag_aws_autoscaling_groupName": "xxx",
"ec2_virtualization_type": "hvm",
"ec2_vpc_id": "vpc-xxx"
}
}
}
"tag_Service_Foo": [
"54.149.9.198",
"52.11.22.29",
"52.11.0.3"
],
}
您需要做的是在 ec2.py
上创建您自己的包装器(比如 my_ec2.py
),它将 post 处理输出。想法是使用 behavioral hostvar ansible_ssh_host
. You can use any language not only python. As long as it prints valid json on stdout you're good to go. Reference if needed.
这只是一点点工作。但希望 sudo 代码能有所帮助:
output_json_map = new map
for each group in <ec2_output>: # e.g. tag_Service_Foo, I think there would be another
# key in the output that contains list of group names.
for each ip_address in group:
hname = ec2_output._meta.hostvars.find(ip_address).find(ec2_tag_Name)
# Add new host to the group member list
output_json_map.add(key=group, value=hname)
copy all vars from ec2_output._meta.hostvars.<ip_address>
to output_json_map._meta.hostvars.<hname>
# Assign the IP address of this host to the ansible_ssh_host
# in hostvars for this host
output_json_map.add(key=_meta.hostvars.<hname>.ansible_ssh_host,
value=ip_address)
output_json_map.add(key=_meta.hostvars.find(ip_address).ansible_ssh_host,
value=ip_address)
print output_json_map to stdout
例如对于您的示例,my_ec2.py
的输出应为:
{
"_meta": {
"hostvars": {
"main-server": {
"ansible_ssh_host": "54.149.9.198"
--- snip ---
"ec2_tag_Name": "main-server",
--- snip ---
},
"extra-server": {
"ansible_ssh_host": "52.11.22.29"
--- snip ---
"ec2_tag_Name": "extra-server",
--- snip ---
},
<other hosts from all groups>
}
}
"tag_Service_Foo": [
"main-server",
"extra-server",
<other hosts in this group>
],
"some other group": [
<hosts in this group>,
...
],
}
显然,使用此 my_ec2.py
而不是 ec2.py
作为库存文件。 :-)
--编辑--
1) In the groups, can I only refer to things by one name? 2) There's
no notion of an alias? 3) I'm wondering if I could use the IP addr in
the groups and just modify the _meta part or if I need to do it all?
是*,否和否。
* 从技术上讲,首先是应该不是。让我解释一下。
我们在这里做的事情可以用这样的静态清单文件来完成:
原始 ec2.py
正在返回 json 等同于以下库存文件:
[tag_Service_Foo]
54.149.9.198 ec2_tag_Name="main-server" ec2_previous_state_code="0" ...
52.11.22.29 ec2_tag_Name="extra-server" ec2_previous_state_code="0" ...
我们的新 my_ec2.py
returns 这个:
[tag_Service_Foo]
main-server ansible_ssh_host="54.149.9.198" ec2_tag_Name="main-server" ec2_previous_state_code="0" ...
extra-server ansible_ssh_host="52.11.22.29" ec2_tag_Name="extra-server" ec2_previous_state_code="0" ...
# Technically it's possible to create "an alias" for main-server like this:
main-server-alias ansible_ssh_host="54.149.9.198" ec2_tag_Name="main-server" ec2_previous_state_code="0" ...
现在您可以 运行 与主机列表中的 main-server-alias
一起玩,ansible 将在 54.149.9.198
.
上执行它
BUT,这是一个很大的 BUT,当你 运行 玩 'all' 作为主机模式 ansible 时 运行 main-server-alias
和 main-server
上的任务。因此,您创建的是一个上下文中的别名和另一个上下文中的新主机。我还没有测试这个 但部分 所以如果你发现其他情况请回来纠正我。
HTH
如果你把
vpc_destination_variable = Name
在您的 ec2.ini
文件中,这也应该有效。
对于较新的版本,至少适用于 Ansible 的 2.9 和 2.10 版本,aws_ec2
插件现在允许将其作为一个简单的配置,而无需围绕 [=36 创建任何 warper =]ec2.py.
这可以使用参数组合来完成 hostnames
and compose
。
所以诀窍是通过 hostnames
参数更改 EC2 实例的名称,使其具有人类可读的内容——例如来自实例上的 AWS 标签——然后使用 compose
参数将 ansible_host
设置为 private_ip_address
、public_ip_address
、private_dns_name
或 public_dns_name
以允许连接,仍然。
这里是插件的最小配置以允许这样做:
plugin: aws_ec2
hostnames:
- tag:Name
# ^-- Given that you indeed have a tag named "Name" on your EC2 instances
compose:
ansible_host: public_dns_address
请注意,在 AWS 中,标签不是唯一的,因此您可以使用相同名称标记多个实例,但在 Ansible 中,主机名 是唯一的。这意味着您最好使用 tag:Name
后缀和真正独特的东西组成名称,例如实例 ID。
类似于:
plugin: aws_ec2
hostnames:
- name: 'instance-id'
separator: '_'
prefix: 'tag:Name'
compose:
ansible_host: public_dns_address
我有一本用于处理 EC2 实例的 Ansible 剧本。我正在使用动态清单 (ec2.py) 来获取我想要使用的实例组 (hosts: tag_Service_Foo
)。当我 运行 它时,它会产生如下输出:
GATHERING FACTS ***************************************************************
ok: [54.149.9.198]
ok: [52.11.22.29]
ok: [52.11.0.3]
但是,我可以从 Amazon 获取特定实例的 "Name" 标签(我这样做并将其存储在一个变量中以供剧本的几个部分使用)。
有没有办法让 Ansible 在显示进度时使用这个字符串作为主机名?我希望看到更具描述性的内容(因为我没有记住 IP):
GATHERING FACTS ***************************************************************
ok: [main-server]
ok: [extra-server]
ok: [my-cool-server]
ec2.py
库存脚本的输出看起来像这样(t运行cated;它很长)。
{
"_meta": {
"hostvars": {
"54.149.9.198": {
"ec2__in_monitoring_element": false,
"ec2_ami_launch_index": "0",
"ec2_architecture": "x86_64",
"ec2_client_token": "xxx",
"ec2_dns_name": "xxx",
"ec2_ebs_optimized": false,
"ec2_eventsSet": "",
"ec2_group_name": "",
"ec2_hypervisor": "xen",
"ec2_id": "i-xxx",
"ec2_image_id": "ami-xxx",
"ec2_instance_type": "xxx",
"ec2_ip_address": "xxx",
"ec2_item": "",
"ec2_kernel": "",
"ec2_key_name": "xxx",
"ec2_launch_time": "xxx",
"ec2_monitored": xxx,
"ec2_monitoring": "",
"ec2_monitoring_state": "xxx",
"ec2_persistent": false,
"ec2_placement": "xxx",
"ec2_platform": "",
"ec2_previous_state": "",
"ec2_previous_state_code": 0,
"ec2_private_dns_name": "xxx",
"ec2_private_ip_address": "xxx",
"ec2_public_dns_name": "xxx",
"ec2_ramdisk": "",
"ec2_reason": "",
"ec2_region": "xxx",
"ec2_requester_id": "",
"ec2_root_device_name": "/dev/xvda",
"ec2_root_device_type": "ebs",
"ec2_security_group_ids": "xxx",
"ec2_security_group_names": "xxx",
"ec2_sourceDestCheck": "true",
"ec2_spot_instance_request_id": "",
"ec2_state": "running",
"ec2_state_code": 16,
"ec2_state_reason": "",
"ec2_subnet_id": "subnet-xxx",
"ec2_tag_Name": "main-server",
"ec2_tag_aws_autoscaling_groupName": "xxx",
"ec2_virtualization_type": "hvm",
"ec2_vpc_id": "vpc-xxx"
}
}
}
"tag_Service_Foo": [
"54.149.9.198",
"52.11.22.29",
"52.11.0.3"
],
}
您需要做的是在 ec2.py
上创建您自己的包装器(比如 my_ec2.py
),它将 post 处理输出。想法是使用 behavioral hostvar ansible_ssh_host
. You can use any language not only python. As long as it prints valid json on stdout you're good to go. Reference if needed.
这只是一点点工作。但希望 sudo 代码能有所帮助:
output_json_map = new map
for each group in <ec2_output>: # e.g. tag_Service_Foo, I think there would be another
# key in the output that contains list of group names.
for each ip_address in group:
hname = ec2_output._meta.hostvars.find(ip_address).find(ec2_tag_Name)
# Add new host to the group member list
output_json_map.add(key=group, value=hname)
copy all vars from ec2_output._meta.hostvars.<ip_address>
to output_json_map._meta.hostvars.<hname>
# Assign the IP address of this host to the ansible_ssh_host
# in hostvars for this host
output_json_map.add(key=_meta.hostvars.<hname>.ansible_ssh_host,
value=ip_address)
output_json_map.add(key=_meta.hostvars.find(ip_address).ansible_ssh_host,
value=ip_address)
print output_json_map to stdout
例如对于您的示例,my_ec2.py
的输出应为:
{
"_meta": {
"hostvars": {
"main-server": {
"ansible_ssh_host": "54.149.9.198"
--- snip ---
"ec2_tag_Name": "main-server",
--- snip ---
},
"extra-server": {
"ansible_ssh_host": "52.11.22.29"
--- snip ---
"ec2_tag_Name": "extra-server",
--- snip ---
},
<other hosts from all groups>
}
}
"tag_Service_Foo": [
"main-server",
"extra-server",
<other hosts in this group>
],
"some other group": [
<hosts in this group>,
...
],
}
显然,使用此 my_ec2.py
而不是 ec2.py
作为库存文件。 :-)
--编辑--
1) In the groups, can I only refer to things by one name? 2) There's no notion of an alias? 3) I'm wondering if I could use the IP addr in the groups and just modify the _meta part or if I need to do it all?
是*,否和否。
* 从技术上讲,首先是应该不是。让我解释一下。
我们在这里做的事情可以用这样的静态清单文件来完成:
原始 ec2.py
正在返回 json 等同于以下库存文件:
[tag_Service_Foo]
54.149.9.198 ec2_tag_Name="main-server" ec2_previous_state_code="0" ...
52.11.22.29 ec2_tag_Name="extra-server" ec2_previous_state_code="0" ...
我们的新 my_ec2.py
returns 这个:
[tag_Service_Foo]
main-server ansible_ssh_host="54.149.9.198" ec2_tag_Name="main-server" ec2_previous_state_code="0" ...
extra-server ansible_ssh_host="52.11.22.29" ec2_tag_Name="extra-server" ec2_previous_state_code="0" ...
# Technically it's possible to create "an alias" for main-server like this:
main-server-alias ansible_ssh_host="54.149.9.198" ec2_tag_Name="main-server" ec2_previous_state_code="0" ...
现在您可以 运行 与主机列表中的 main-server-alias
一起玩,ansible 将在 54.149.9.198
.
BUT,这是一个很大的 BUT,当你 运行 玩 'all' 作为主机模式 ansible 时 运行 main-server-alias
和 main-server
上的任务。因此,您创建的是一个上下文中的别名和另一个上下文中的新主机。我还没有测试这个 但部分 所以如果你发现其他情况请回来纠正我。
HTH
如果你把
vpc_destination_variable = Name
在您的 ec2.ini
文件中,这也应该有效。
对于较新的版本,至少适用于 Ansible 的 2.9 和 2.10 版本,aws_ec2
插件现在允许将其作为一个简单的配置,而无需围绕 [=36 创建任何 warper =]ec2.py.
这可以使用参数组合来完成 hostnames
and compose
。
所以诀窍是通过 hostnames
参数更改 EC2 实例的名称,使其具有人类可读的内容——例如来自实例上的 AWS 标签——然后使用 compose
参数将 ansible_host
设置为 private_ip_address
、public_ip_address
、private_dns_name
或 public_dns_name
以允许连接,仍然。
这里是插件的最小配置以允许这样做:
plugin: aws_ec2
hostnames:
- tag:Name
# ^-- Given that you indeed have a tag named "Name" on your EC2 instances
compose:
ansible_host: public_dns_address
请注意,在 AWS 中,标签不是唯一的,因此您可以使用相同名称标记多个实例,但在 Ansible 中,主机名 是唯一的。这意味着您最好使用 tag:Name
后缀和真正独特的东西组成名称,例如实例 ID。
类似于:
plugin: aws_ec2
hostnames:
- name: 'instance-id'
separator: '_'
prefix: 'tag:Name'
compose:
ansible_host: public_dns_address