How to encrypt ansible-vault in the TLS certificate¶
先週、Sidのansibleパッケージが1.4.5+dfsg-1から1.5.3+dfsg-1に上がったので、待望のansible-vaultを使ってみました。パスワードなどを暗号化するために使うのが主でしょうが、今回の私の目的は、TLS証明書を及びその秘密鍵の暗号化です。仕事で使っているplaybookに、PEM形式の証明書や秘密鍵を含めるのがいやだったのが動機です。
IMAPサーバ用のplaybookを例にします。
.
|-- development
|-- group_vars
| |-- all
| |-- development
| `-- production
|-- imapd.yml
|-- production
|-- roles
(snip)
| |-- dovecot
| | |-- handlers
| | | `-- main.yml
| | |-- tasks
| | | `-- main.yml
| | |-- templates
(snip)
| | | |-- 10-ssl.conf.j2
(snip)
| | | |-- key.j2
| | | `-- cert.j2
| | `-- vars
| | `-- main.yml
(snip)
`-- site.yml
ansible-vaultで暗号化する対象は、roles/dovecot/templatesディレクトリの下にある、key.j2とcert.j2の2つのテンプレートの中に出力する文字列です。 証明書とprivate keyを配布するだけなら、filesディレクトリの下に、証明書およびprivate keyファイル自体を配置し、copyモジュールでコピーすれば良いだけです。 しかし、 ドキュメントにもあるとおり ansible-vaultで対象に暗号化の対象にできるのは各種の変数だけなので、filesディレクトリ下の添付ファイルは復号できません。そこで、templateモジュールを使う必要があります。暗号化する文字列自体は、roles/dovecot/vars/main.ymlの中に記述します。
PEM形式の文字列は、
-----BEGIN CERTIFICATE-----
MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE
AwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x
CzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW
(snip)
-----END CERTIFICATE-----
のような形式になっているので、これをtemplateモジュールを使って、ファイルを配置するには、templates/cert.j2などのテンプレートに、
{{ cert_pem }}
とだけ記述し、vars/main.ymlには、
---
- cert_pem: "-----BEGIN CERTIFICATE-----\nMIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE\nAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x\nCzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW\n...(snip)...\n-----END CERTIFICATE-----"
- key_pem: "..."
のように、改行を”n”に変更して一行の文字列とし、それをダブルクォートかシングルクォートで括って指定します。 これで動作確認ができたら、vars/main.ymlを暗号化します。
$ ansible-vault encrypt roles/dovecot/vars/main.yml
暗号化されたファイルは下記のようになります。
$ANSIBLE_VAULT;1.1;AES256
39613864343833373066386636333338653831383630623938643138366230323336656234326234
3833663562396237393333363665643631653331386566660a653530326636666137633731373361
34653163626664376432393433303435333433303535626437623935313962626430643038623464
(snip)
暗号化された変数を使って、playbookを実行するには、 --ask-vault-pass
オプションをつけてansible-playbookコマンドを実行すれば良いだけです。
このオプションをつけると、実行時にだけメモリ上に復号されます。
まとめ¶
今まで、パスワードなどはvars_promptで都度入力し、TLS証明書&秘密鍵などは別途配布する、という方法でやっていました。 これでplaybook自体にansible-vaultで暗号化して管理できるので、vautl passwordのみ、keepassなどで管理すれば良さそうです。