😎

[Ansible]AWSモジュールを使って、EC2インスタンスのメタデータを取得する

2021/05/02に公開

前回の記事では、Ansible のインベントリプラグインを使用してEC2インスタンスを動的に取得する方法について紹介しました。

[Ansible]インベントリプラグインを使ってEC2インスタンス情報を動的に取得する

本記事は、AWS モジュール(AWS コレクション)を使って、EC2 インスタンスのメタデータを取得する方法について紹介します。実行対象のインスタンスタイプやリージョンによって処理を分岐させる場合に利用できます。

Ansible のバージョン

手元の実行環境です。

$ ansible --version
ansible 2.10.8
  config file = /home/ansible/workspace/ansible.cfg
  configured module search path = ['/home/ansible/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.8/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.8.9 (default, Apr 10 2021, 15:55:09) [GCC 8.3.0]

$ pip list | grep ansible
ansible           3.2.0
ansible-base      2.10.8
ansible-lint      5.0.7

$ pip list | grep boto
boto              2.49.0
boto3             1.17.62
botocore          1.20.62

EC2インスタンス例

今回は ansible-target-node01~05 という EC2 インスタンスが実行されているとします。Application というタグで EC2 インスタンスをグルーピングしています。

Nameタグ Applicationタグ インスタンスタイプ
ansible-target-node01 なし t3a.medium
ansible-target-node02 なし t3a.medium
ansible-target-node03 bar t3a.medium
ansible-target-node04 foo t3a.medium
ansible-target-node05 foo t3.medium

AWS コレクションのインストール

Ansible Galaxy から amazon.aws コレクションをインストールします。

$ ansible-galaxy collection install amazon.aws
$ ansible-galaxy collection list | grep amazon.aws
amazon.aws                    1.4.1

また、ホスト上で boto3 と botocore が必要です。

$ pip install boto3 botocore

インベントリの設定は前回の記事をご参照ください。

プレイブック例

# playbook.yml
---
- name: Example dynamic inventory
  hosts: "{{ target_hosts }}"

  vars:
    ansible_user: ec2-user
    ansible_ssh_private_key_file: ~/.ssh/<KEY PAIR>.pem

  pre_tasks:
    - name: Gather ec2_metadata
      amazon.aws.ec2_metadata_facts:

  tasks:
    # EC2インスタンスメタデータで取得できるすべての値を表示
    - name: Print all EC2 metadata
      debug:
        msg: |-
          {%- for key in hostvars[tags.Name] if 'ansible_ec2' in key %}
            {{ key }}:{{ hostvars[tags.Name][key] }}
          {%- endfor %}

    # EC2インスタンスIDを表示
    - name: Print EC2 instance id
      debug:
        var: ansible_ec2_instance_id

    # インスタンスタイプがt3a.mediumの場合のみ実行
    - name: Print only t3a.medium
      debug:
        msg: "This instance is a t3a.medium"
      when: ansible_ec2_instance_type == "t3a.medium"

pre_taskamazon.aws.ec2_metadata_facts で EC2 インスタンスメタデータを取得します。何が取得できるかはドキュメントには記載されていないので、上記のようなプレイブックですべて表示しておくことでデバッグしやすくなります。

when: ansible_ec2_instance_type において指定したインスタンスタイプの場合のみ処理されます。

# Applicationタグ: foo(tag_Name_foo)のEC2インスタンスに対して実行する
$ ansible-playbook -i aws_ec2.yml sample.yml -e "target_hosts=tag_Name_foo"

PLAY [Example dynamic inventory] ***********************************************************************************************

...(省略)...

TASK [Print only t3a.medium] ************************************************************************************************
skipping: [ansible-target-node05]
ok: [ansible-target-node04] => {
    "msg": "This instance is a t3a.medium"
}

参考

Discussion