1

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 から特定のインスタンスの「名前」タグをフェッチすることはできます (これを実行し、プレイブックのいくつかの部分で使用するために変数に格納します)。

進行状況を表示するときにホスト名にこの文字列を使用するように Ansible を取得する方法はありますか? もっと説明的なものを見たいと思います(IPを記憶していないため):

GATHERING FACTS ***************************************************************
ok: [main-server]
ok: [extra-server]
ok: [my-cool-server]

インベントリ スクリプトの出力はec2.py次のようになります (省略されています。非常に長いです)。

{
  "_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"
  ],
}
4

3 に答える 3

2

あなたがする必要があるのは、出力を後処理する独自のラッパー(たとえばmy_ec2.py)を作成することです。ec2.pyアイデアは、動作する hostvaransible_ssh_hostを使用することです。Python だけでなく、どの言語でも使用できます。標準出力に有効なjsonを出力する限り、問題ありません。必要に応じて参照してください。

ちょっとした作業になります。しかし、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) グループ内では、1 つの名前だけで参照できますか? 2) エイリアスの概念はないのですか? 3) グループ内の IP アドレスを使用して _meta 部分を変更するだけでよいのか、それともすべてを行う必要があるのか​​疑問に思っています。

はい*、いいえ、いいえ。


* 技術的には、まず yes を no にする必要があります。説明させてください。

ここで行っていることは、次のような静的インベントリ ファイルで実行できます。

オリジナル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戻り値は次のとおりです。

[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" ...

これで、ホスト リストでplay を実行できるようにmain-server-aliasなり、ansible でそれを実行できます54.149.9.198

BUT、これは大きな問題ですが、「all」を指定してプレイを実行すると、ホスト パターン ansible がmain-server-aliasと同様にタスクを実行するためmain-serverです。したがって、作成したものは、あるコンテキストではエイリアスであり、別のコンテキストでは新しいホストです。私はこの部分をテストしていませんが、そうでない場合は戻ってきて修正してください。

HTH

于 2015-03-30T15:41:22.703 に答える
0

Ansible のバージョン 2.9 および 2.10 で動作する最近のバージョンでは、プラグインはec2.pyaws_ec2の周りにワーパーを作成する必要なく、単純な構成としてこれを許可するようになりました。

hostnamesこれは、パラメータとの組み合わせを使用して実行できますcompose

したがって、トリックは、hostnamesパラメーターを介して EC2 インスタンスの名前を人間が読める名前に変更することです (たとえば、インスタンスの AWS タグから)。次に、composeパラメーターを使用して を、、またはに設定しansible_hostて、接続を許可します。 、 まだ。private_ip_addresspublic_ip_addressprivate_dns_namepublic_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
于 2021-10-21T19:26:41.237 に答える