zaki work log

作業ログやら生活ログやらなんやら

[Ansible / AWS] ダイナミックインベントリを使ってEC2接続先を動的に取得してAnsible実行お試し

Ansibleのダイナミックインベントリを使ったEC2アクセスについて、以前試したような試してないような記憶がおぼろげで、メモも無かったので簡単にまとめてみた。

docs.ansible.com

必要パッケージ

$ pip install boto3 botocore

クラウド上のEC2状態

こんな感じでpublic ipありでAmazon LinuxのEC2が3台動いてる。

f:id:zaki-hmkc:20210621085524p:plain

今回はダイナミックインベントリを使って、このEC2の「IPアドレスをチェックしてインベントリに指定する」という作業を省略する方法について確認する。

アクセスキー設定

後述のインベントリファイルのパラメタにaws_access_keyaws_secret_keyはあるけど、今回はansible-playbookを実行する側に環境変数で設定。

AWS_SECRET_ACCESS_KEY=****
AWS_ACCESS_KEY_ID=****

インベントリファイル

見落としててプチハマりしたんだけど、インベントリファイル名は指定があり、aws_ec2.ymlまたはaws_ec2.yamlで終わるファイル名でなければならない。

Uses a YAML configuration file that ends with aws_ec2.(yml|yaml).

これを踏まえてインベントリのファイル名はaws_ec2.ymlや、分かりやすいようにinventory_aws_ec2.ymlなどにしておく。
プラグインamazon.awsコレクションのaws_ec2インベントリプラグインを指定する。これはamazon.awsコレクションをansible-galaxy collection install amazon.awsでインストールすれば使用できる。
(Ansibleのインストールをcoreのみでなくフルセットで入れてれば付属しているはず)

---
plugin: amazon.aws.aws_ec2

最低限動かすにはこれだけの記述と、トークン情報を環境変数で設定しておけば、

$ ansible-inventory -i inventory-aws_ec2.yml --graph
@all:
  |--@aws_ec2:
  |  |--ec2-13-112-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-13-113-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-18-179-***-***.ap-northeast-1.compute.amazonaws.com
  |--@ungrouped:
$

このようにホストグループallでEC2のホスト情報を取得できるようになる。
リージョン指定しないと全リージョンなめてる感じなのかそこそこ時間かかるので、以下のようにリージョンを特定できるなら指定しておけば速度が少し上がる。

---
plugin: amazon.aws.aws_ec2
regions:
  - ap-northeast-1

プレイブック

allまたはaws_ec2グループは使えるので、これでお試し。

---
- hosts: all
  gather_facts: false

  tasks:
    - name: ping
      ping:
$ ansible-playbook -i inventory-aws_ec2.yml --user ec2-user --private-key=~/.ssh/id_aws_terraform playbook.yml 

PLAY [all] ************************************************************************************************************

TASK [ping] ***********************************************************************************************************
[WARNING]: Platform linux on host ec2-18-179-***-***.ap-northeast-1.compute.amazonaws.com is using the discovered Python
interpreter at /usr/bin/python, but future installation of another Python interpreter could change the meaning of that
path. See https://docs.ansible.com/ansible/2.10/reference_appendices/interpreter_discovery.html for more information.
ok: [ec2-18-179-***-***.ap-northeast-1.compute.amazonaws.com]
[WARNING]: Platform linux on host ec2-13-113-***-***.ap-northeast-1.compute.amazonaws.com is using the discovered Python
interpreter at /usr/bin/python, but future installation of another Python interpreter could change the meaning of that
path. See https://docs.ansible.com/ansible/2.10/reference_appendices/interpreter_discovery.html for more information.
ok: [ec2-13-113-***-***.ap-northeast-1.compute.amazonaws.com]
[WARNING]: Platform linux on host ec2-13-112-***-***.ap-northeast-1.compute.amazonaws.com is using the discovered
Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change the meaning
of that path. See https://docs.ansible.com/ansible/2.10/reference_appendices/interpreter_discovery.html for more
information.
ok: [ec2-13-112-***-***.ap-northeast-1.compute.amazonaws.com]

PLAY RECAP ************************************************************************************************************
ec2-13-112-***-***.ap-northeast-1.compute.amazonaws.com : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
ec2-13-113-***-***.ap-northeast-1.compute.amazonaws.com : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
ec2-18-179-***-***.ap-northeast-1.compute.amazonaws.com : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

(a2.10) [zaki@cloud-dev aws (master)]$ 

Pythonインタプリタのパスについての警告がでてるけど、SSHアクセスしてpingモジュールの実行に成功することを確認。

ホストグループ指定の設定

今回はタグを使ってみる。

現状

  • bastion-0
  • app
  • db

の3種のNameタグがつけられたEC2インスタンスがあるので、(各タグが設定されたEC2は1台ずつしかないので面白くないけど)タグ名を使ってホストグループ設定できるようにしてみる。

設定はkeyed_groupsでキー名にtagsとどのタグを使うかを指定する。今回はNameタグなのでtags.Nameを指定。

---
plugin: amazon.aws.aws_ec2
regions:
  - ap-northeast-1
keyed_groups:
  - key: tags.Name
$ ansible-inventory -i inventory-aws_ec2.yml --graph
@all:
  |--@_app:
  |  |--ec2-13-112-***-***.ap-northeast-1.compute.amazonaws.com
  |--@_bastion_0:
  |  |--ec2-13-113-***-***.ap-northeast-1.compute.amazonaws.com
  |--@_db:
  |  |--ec2-18-179-***-***.ap-northeast-1.compute.amazonaws.com
  |--@aws_ec2:
  |  |--ec2-13-112-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-13-113-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-18-179-***-***.ap-northeast-1.compute.amazonaws.com
  |--@ungrouped:
$

この通り、Nameタグを使ったグルーピングができるようになる。
グループ名は_タグ名がデフォルトだけど、prefix: tagname_とか指定すれば、prefix指定ができる。

---
plugin: amazon.aws.aws_ec2
regions:
  - ap-northeast-1
keyed_groups:
  - key: tags.Name
    prefix: tagname_

この内容であれば、

$ ansible-inventory -i inventory-aws_ec2.yml --graph
@all:
  |--@aws_ec2:
  |  |--ec2-13-112-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-13-113-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-18-179-***-***.ap-northeast-1.compute.amazonaws.com
  |--@tagname__app:
  |  |--ec2-13-112-***-***.ap-northeast-1.compute.amazonaws.com
  |--@tagname__bastion_0:
  |  |--ec2-13-113-***-***.ap-northeast-1.compute.amazonaws.com
  |--@tagname__db:
  |  |--ec2-18-179-***-***.ap-northeast-1.compute.amazonaws.com
  |--@ungrouped:

こんな感じ。 あ、_が余計だな。

グループのキーとして指定できる一覧がぱっと見見つからないけど、Examplesを見た感じ、アーキテクチャインスタンスタイプ、リージョンなどいろいろ指定できそう。(AZは無い?)

  - key: architecture
  - key: instance_type
  - key: placement.region
$ ansible-inventory -i inventory-aws_ec2.yml --graph
@all:
  |--@_ap_northeast_1:
  |  |--ec2-13-112-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-13-113-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-18-179-***-***.ap-northeast-1.compute.amazonaws.com
  |--@_t3_nano:
  |  |--ec2-13-112-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-13-113-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-18-179-***-***.ap-northeast-1.compute.amazonaws.com
  |--@_x86_64:
  |  |--ec2-13-112-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-13-113-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-18-179-***-***.ap-northeast-1.compute.amazonaws.com
  |--@aws_ec2:
  |  |--ec2-13-112-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-13-113-***-***.ap-northeast-1.compute.amazonaws.com
  |  |--ec2-18-179-***-***.ap-northeast-1.compute.amazonaws.com
  |--@tagname__app:
  |  |--ec2-13-112-***-***.ap-northeast-1.compute.amazonaws.com
  |--@tagname__bastion_0:
  |  |--ec2-13-113-***-***.ap-northeast-1.compute.amazonaws.com
  |--@tagname__db:
  |  |--ec2-18-179-***-***.ap-northeast-1.compute.amazonaws.com
  |--@ungrouped:

環境

$ ansible --version
ansible 2.10.7
  config file = /home/zaki/.ansible.cfg
  configured module search path = ['/home/zaki/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/zaki/src/ansible-sample/venv/a2.10/lib64/python3.6/site-packages/ansible
  executable location = /home/zaki/src/ansible-sample/venv/a2.10/bin/ansible
  python version = 3.6.8 (default, Nov 16 2020, 16:55:22) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]

まとめ

aws_ec2ダイナミックインベントリを使うことで、EC2のIPアドレスを把握してなくても予め設定しておいたタグ名などを使ってターゲットノードとしてアクセスできることを確認できた。
クラウドのコンピュートインスタンスをリソースを使い捨てにするためIPアドレスを固定せずに使用する場合、クラウドサービスのAPIを使って動的にアドレスを取得する仕組みがあるのは便利。
対象のアドレスをダイナミックインベントリを使って取得した後の認証などは従来と同じなので、SSH公開鍵認証設定などを使ってアクセスする。