Ansible
gce
gcp

[覚書] ansible-inventoryでGCEインスタンスの情報を取得する

最近 Ansible の勉強を始めて、その検証環境として GCE インスタンスを複数作って色々と試している。
そんな中、インスタンス起動のたびに変わる IP アドレスをインベントリファイルに反映するのが面倒になり、GCE Dynamic Inventory というものを使ってみようと思った。
その時に結構苦労したので、GCE Dynamic Inventory の利用手順を覚書として記事にしてみた。

バージョン

  • Ansible: 2.7.0
  • Python: 2.7.15

必要なパッケージ

requestsgoogle-auth が必要。
下記のコマンドでインストールする。

pip install requests google-auth

インベントリファイルを作成する

下記のようなインベントリファイルを作成する。
ただし、ファイル名は ".gcp.yml"、".gcp.yaml"、".gcp_compute.yml"、".gcp_compute.yaml" で終わる必要がある。
"<your-*>" は環境に合わせて設定する。

*.gcp.yml
plugin: gcp_compute
zones:
  - <your-zone>
projects:
  # プロジェクト ID を指定する
  - <your-project-ID>
scopes:
  - https://www.googleapis.com/auth/compute
service_account_file: <your-service-account-file-path>
auth_kind: serviceaccount
filters:
  - <your-filters>
hostnames:
  # [ name | public_ip | private_ip ] のどれかを指定できる
  - name

サービスアカウントファイルは json 形式でダウンロードしておくと良い。
必要であれば、その他パラメータを追加すれば良いと思うが、私はこれ以上は試していない。

ansible.cfg を編集する

上記のインベントリファイルを作成し、実行しただけでは gcp_compute プラグインが呼び出されない。
ここに結構ハマった。。。

Ansible の初期設定では、gcp_compute プラグインは呼び出されない設定になっている。
そこで、/etc/ansible/ansible.cfg の 300 行目付近にプラグインの設定を記述する場所がある(はずな)ので、そこのコメントを外し、gcp_compute を追記する。

[inventory]
# enable inventory plugins, default: 'host_list', 'script', 'yaml', 'ini'
enable_plugins = gcp_compute, host_list, virtualbox, yaml, constructed

ansible-inventory -i <your-file-name>.gcp.yml --list を実行する

見出しの通り、ansible-inventory -i <your-file-name>.gcp.yml --list を実行すれば、起動している GCE インスタンスから情報を取得することができる。
ただし、すべての情報が取得されるので、必要な情報を見つけるのがこれまた面倒である。

ansible-inventory -i <your-file-name>.gcp.yml --graph のようにオプションを --graph にするとホスト名かIPアドレスのどちらかを取得できる。
なんか惜しいので、jq 使って host-name, IP address みたいな感じで IP アドレスだけ抜き出したい。

(追記:2018/10/20)
下記のコマンドで出力結果をインベントリファイルにコピペするだけで良くなったかな。
もっと良い方法があると思うけど。。。

ansible-inventory -i <file-name>.gcp.yml --list \
| jq -c '._meta.hostvars[] | { (.name): .networkInterfaces[0].accessConfigs[0].natIP }' \
| sed -r -e 's/\{(.+)\}/\1/g' -e 's/"//g' -e 's/(.+):(.+)/\1 ansible_host=\2/g'

# 出力例
host1 ansible_host=192.168.1.1
host2 ansible_host=192.168.1.2