Ansibleの実行対象AWSアカウントを事前にチェックして事故防止

はじめに

AnsibleでAWSリソースを操作する場合、気をつけなければいけないのが対象アカウント間違いです。
これはaws cliでも同じですが、作業前にaws configure listで確認するしかなく、ヒューマンエラーが起こりやすいです。

そこで、Ansibleで現在有効になっているプロファイルと実行対象のAWSアカウントを比較し、違っていたらタスクをfailさせ、予期せぬアカウントに対するAnsible実行を抑止します。

前提

  • aws cliがインストールされている必要があります。
  • credential情報は環境変数かaws configureでセットしてある必要があります。

sample

ディレクトリ構成

ディレクトリ構成
site.yml
roles/
|--account_check/
|  |--tasks/
|  |  |--main.yml
hosts/aws    #inventory
host_vars/
|--localhost.yml

inventory

今回はaws cliをlocalhostで実行するので、下記のようなインベントリファイルを用意します。

hosts/aws
[aws]
localhost

vars

こんな感じに変数を定義します。今回はhost_varsで定義しました。

host_vars/localhost.yml
---
my_vars:
  aws:
    common:
      account_id: XXXXXXXXXXXX

Role

shellモジュールでaws cliにより現在のプロファイルでセットされているAWSアカウントIDを取得し、varsに設定されているアカウントID(実行対象)と比較して違っていたらfailさせます。

failed_whenでfailさせてもいいのですが、カスタムメッセージを出したほうがわかりやすいのでfailモジュールを利用します。

roles/account_check/tasks/main.yml
---
- name: AWSアカウントID取得
  shell: >-
    aws sts get-caller-identity \
     --query 'Account' \
     --output text
  check_mode: no
  changed_when: false
  register: aws_id

- name: AWSアカウントIDチェック
  fail:
    msg: "Target AWS account is wrong!!"
  check_mode: no
  when: "aws_id.stdout != '{{ my_vars.aws.common.account_id }}'"

site.yml

tagsにalwaysを指定することで、タグを指定しての実行においても必ず実行されるようになります。

site.yml
---
- name: account_check
  hosts: localhost
  connection: local
  roles:
    - role: account_check
  tags:
    - always
    - account_check

実行

Command
$ ansible-playbook -i hosts/aws -l localhost site.yml

まとめ

このRoleを一番最初に実行すると、万が一対象アカウントとプロファイルのアカウントが違う場合、後続タスクが実行されないので安全です。

参考

AnsibleでAWSリソースを管理するシリーズ