Ansibleのlookupを使って秘密鍵を配備する

2015.12.11

SHU-METAL DEATH。 現在、首都高で渋滞にハマっているので、Ansibleの小ネタシリーズのストックをはきだしています。

Ansibleでサーバの構成管理を行う時、サーバに秘密鍵を配備する場合があります。 この時、秘密鍵を変数化した上でvaultで暗号化する方法が一般的に知られています(Ansible Vaultを利用して秘密情報を暗号化する)。 しかし、vaultパスワードの設定やパスワードファイルの指定が意外とメンドクサイ。 今回はvaultを利用しない方法を紹介します。

構成管理とバージョン管理

秘密鍵を暗号化しない方法を説明する前に、構成管理とバージョン管理について整理しておきます。

Ansibleなど構成管理ツールを利用するメリットのひとつは、サーバの設定を設定ファイルなどで定義し、そのファイルをバージョン管理できることです。 リポジトリでバージョン管理しておけば、変更履歴を追うことができます。 また、特定のリビジョンの設定ファイルを取得すれば、ある時点でのサーバを復元することもできるわけです(必要にならないことを祈りますが...)

ところが、AWSのアクセスキーや秘密鍵など、バージョン管理に含めることが御法度な情報もあるのが現実です。 Admin権限を持ったAWSのアクセスキーなどがGitHubなどで漏洩すると洒落になりません...。 プライベートリポジトリとはいえ、鍵を扱うのは慎重になるべきです。

原則として、バージョン管理システムにAWSのアクセスキーや秘密鍵を登録すべきではありません。 しかし、すべての情報をバージョン管理するメリットが大きいことも事実です。 このような背景から、Ansibleでは、vaultによる暗号化をサポートしており、機密情報は暗号化して管理できるようになっています。

lookupプラグインで秘密鍵をコピーする

現実問題として、秘密鍵やAWSのアクセスキーなどは別の管理方針となっていることも多いと思います。 例えば、秘密鍵を.sshディレクトリに、AWSのアクセスキーを.awsディレクトリに保存する、などのルールがあるでしょう。 また、サーバにアクセスするためにはそれらの鍵は必要なので、わざわざバージョン管理システムで多重管理する必要もありません。

このような場合、ローカルファイルをlookupプラグインする方法が有効です。 ローカルファイルを参照し、秘密鍵をサーバに作成するならば、copyモジュールとlookupプラグインを利用して次のように記述できます。

- name: private key for slave server
  copy: dest=~/.ssh/slave.pem mode=600 
        content="{{ lookup('file', '~/.ssh/slave.pem') }}"

まとめ

vaultによる暗号化とローカルファイルのlookupは、どちらが良いかは状況によるでしょう。 どうしてもバージョン管理で管理したい事情があるのであれば、valutによる暗号化一択となります。 しかし、秘密鍵のやりとりを含め、別途管理しているのであれば、lookupでローカルファイルにアクセスする方がベターだと思います。

なお、なんでもlookupした場合、破綻の音しか聞こえないのでご注意ください...。