Ansible-VaultとAWS SecretsManager で、パスワードとかを安全にAnsibleで管理する

# Ansible-VaultとAWS SecretsManager で、パスワードとかを安全にAnsibleで管理する

Ansible-Vault と AWS SecretsManager を組み合わせて、ansibleでパスワードとかを暗号化したメモ

- Ansible-Vault : https://docs.ansible.com/ansible/latest/user_guide/vault.html
- AWS Secrets Manager : https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/intro.html

## やりたいこと

- パスワードとかを、ansibleにそのまま書いて、gitにcommitするのは色々とまずいのでAnsible-Vaultで暗号化する。
- 暗号化のパスワードの管理もいろいろ考えたくないので、AWS Secrets Manager にさせる。


## 方針
- 暗号化のパスワードはAWS Secrets Managerに保管して利用する
   - これでIAMだけ考えればよくなる
- Ansible-Vaultは、ファイル単位の暗号化でなく、フィールド単位での暗号化にする
   - ファイル単位にしちゃうと、gitでみた時に超不便


## やりかたのまとめ
- AWS Secretes Manager からパスワードを標準出力するShell Scriptを作成して、それを `--vault-password-file` に指定する
   - `--vault-password-file` はパスワードが書かれたファイルを指定するが、パスワードを出力する実行ファイルを指定しても動く (inventoryとかと一緒)
   - `ansible.cfg` の `[defaults]` の `vault_password_file` に書いちゃえば、都度指定する必要なくなるので便利
- フィールドの暗号化は、 `ansible-vault encrypt_string` 使って、出力されたものを変数として記載する

## 実行例

### 前提

- AWS Secretes Manager
   - シークレットのタイプは「他の種類のシークレット」
   - シークレット名 : `ansible-vault`
   - シークレットキー : `main`
- IAM
   - 実行する環境で、上記シークレットへのアクセス権限をつける（インスタンスロールとか、アクセスキーとかで）

### AWS Secretes Manager からパスワードを標準出力するShell Script

```bash
#!/bin/bash

aws secretsmanager get-secret-value --secret-id ansible-vault --region ap-northeast-1 | jq -r .SecretString | jq -r .main
```

これを、`vault_pass.sh` で保存、実行権限つけて、、、

### 暗号化

```bash
-> % echo 'MY_PASSWORD' | ansible-vault encrypt_string --stdin-name "db_password" --vault-password-file ./vault_pass.sh
Reading plaintext input from stdin. (ctrl-d to end input)
db_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          36366633366332363266363932633930396137393639663438303663363563373565393664613734
          3435303263666164353935646632303838303363303930390a393639346130386263333239613664
          61343233316234353333363765336438303134323362323732643437336336343933346233383331
          3138343435663363390a653766353066653561316166386662363233613339363039373962656261
          3366
Encryption successful
```

### Playbookへの記載

出力された

```
db_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          36366633366332363266363932633930396137393639663438303663363563373565393664613734
          3435303263666164353935646632303838303363303930390a393639346130386263333239613664
          61343233316234353333363765336438303134323362323732643437336336343933346233383331
          3138343435663363390a653766353066653561316166386662363233613339363039373962656261
          3366
```
をそのまま、variableとして書けばOK

```yaml
- db_user: admusr
- db_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          36366633366332363266363932633930396137393639663438303663363563373565393664613734
          3435303263666164353935646632303838303363303930390a393639346130386263333239613664
          61343233316234353333363765336438303134323362323732643437336336343933346233383331
          3138343435663363390a653766353066653561316166386662363233613339363039373962656261
          3366
```

これでそのままgitにcommitできる

### 実行
`ansible-playbook` を実行する際に、オプションで `--vault-password-file ./vault_pass.sh` をつけて実行するだけでOK


### おまけ

ansible.cfg に

```
[defaults]
vault_password_file=./vault_pass.sh
```

を書いておけば、`--vault-password-file ./vault_pass.sh` を毎回付ける必要なくなる（逆につけると変な動作になるので注意）


# 注意

## `-v` で復号されたものが出力されちゃう問題

FAQ https://docs.ansible.com/ansible/2.6/reference_appendices/faq.html#how-do-i-keep-secret-data-in-my-playbook にある通り `no_log: True` をつければOK