序章

Ansible Vaultは、ユーザーがAnsibleプロジェクト内の値とデータ構造を暗号化できるようにする機能です。 これにより、Ansibleプレイを正常に実行するために必要であるが、パスワードや秘密鍵などの公開されるべきではない機密データを保護する機能が提供されます。 Ansibleは、キーが提供されると、実行時にボールトで暗号化されたコンテンツを自動的に復号化します。

このガイドでは、Ansible Vaultの使用方法を示し、その使用を簡素化するためのいくつかの推奨プラクティスを探ります。 AnsibleコントロールマシンにはUbuntu20.04サーバーを使用します。 リモートホストは必要ありません。

前提条件

フォローするには、root以外のユーザーがいるUbuntu20.04サーバーが必要です。 sudo 特権。 Ubuntu 20.04初期サーバーセットアップガイドに従って、適切な権限を持つユーザーを作成できます。

サーバー上で、Ansibleをインストールして構成する必要があります。 Ubuntu 20.04 へのAnsibleのインストールに関するチュートリアルに従って、適切なパッケージをインストールできます。

サーバーが上記の要件で構成されている場合は、このガイドを続けてください。

Ansible Vaultとは何ですか?

Ansible Vaultは、暗号化されたコンテンツをAnsibleワークフローに透過的に組み込むことができるメカニズムです。 と呼ばれるユーティリティ ansible-vault ディスク上で暗号化することにより、secretsと呼ばれる機密データを保護します。 これらの秘密を通常のAnsibleデータと統合するには、両方とも ansibleansible-playbook アドホックタスクと構造化プレイブックをそれぞれ実行するためのコマンドは、実行時にボールトで暗号化されたコンテンツを復号化することをサポートしています。

Vaultはファイルレベルの粒度で実装されます。つまり、個々のファイルは暗号化されているか、暗号化されていないかのどちらかです。 それは使用します AES256 ユーザー指定のパスワードにキー設定された対称暗号化を提供するアルゴリズム。 これは、コンテンツの暗号化と復号化に同じパスワードが使用されることを意味します。これは、使いやすさの観点から役立ちます。 Ansibleは、プレイブックまたはタスクの実行中に見つかったボールト暗号化ファイルを識別して復号化できます。

Vaultとは何かについて少し理解できたので、Ansibleが提供するツールと既存のワークフローでVaultを使用する方法について説明します。

AnsibleVaultエディターの設定

使用する前に ansible-vault コマンドの場合は、好みのテキストエディタを指定することをお勧めします。 Vaultのコマンドのいくつかは、暗号化されたファイルの内容を操作するためにエディターを開くことを含みます。 Ansibleは EDITOR 好みのエディタを見つけるための環境変数。 これが設定されていない場合、デフォルトで vi.

で編集したくない場合 vi エディター、あなたは設定する必要があります EDITOR 環境内の変数。

注: vi 誤ってセッションを終了するには、Escキーを押して次のように入力します。 :q!、次にEnterを押します。 あなたが精通していない場合 vi エディターでは、行った変更は意図しないものである可能性が高いため、このコマンドは保存せずに終了します。

個々のコマンドのエディターを設定するには、次のように、コマンドの前に環境変数の割り当てを追加します。

  1. EDITOR=nano ansible-vault . . .

これを永続的にするには、 ~/.bashrc ファイル:

  1. nano ~/.bashrc

を追加して、好みのエディタを指定します EDITOR ファイルの終わりへの割り当て:

〜/ .bashrc
export EDITOR=nano

終了したら、ファイルを保存して閉じます。

ファイルを再度ソースして、変更を現在のセッションに読み込みます。

  1. . ~/.bashrc

を表示します EDITOR 設定が適用されたことを確認する変数:

  1. echo $EDITOR
Output
nano

好みのエディターを確立したので、利用可能な操作について話し合うことができます。 ansible-vault 指図。

ansible-vaultで機密ファイルを管理する方法

The ansible-vault コマンドは、Ansible内で暗号化されたコンテンツを管理するためのメインインターフェイスです。 このコマンドは、最初にファイルを暗号化するために使用され、その後、データを表示、編集、または復号化するために使用されます。

新しい暗号化ファイルの作成

Vaultで暗号化された新しいファイルを作成するには、 ansible-vault create 指図。 作成するファイルの名前を渡します。 たとえば、次のような暗号化されたYAMLファイルを作成するには vault.yml 機密変数を保存するには、次のように入力します。

  1. ansible-vault create vault.yml

パスワードを入力して確認するように求められます。

Output
New Vault password: Confirm New Vault password:

パスワードを確認すると、Ansibleはすぐに編集ウィンドウを開き、目的のコンテンツを入力できます。

暗号化機能をテストするには、次のテストテキストを入力します。

vault.yml
Secret information

Ansibleは、ファイルを閉じるときにコンテンツを暗号化します。 ファイルをチェックすると、入力した単語が表示される代わりに、暗号化されたブロックが表示されます。

  1. cat vault.yml
Output
$ANSIBLE_VAULT;1.1;AES256 65316332393532313030636134643235316439336133363531303838376235376635373430336333 3963353630373161356638376361646338353763363434360a363138376163666265336433633664 30336233323664306434626363643731626536643833336638356661396364313666366231616261 3764656365313263620a383666383233626665376364323062393462373266663066366536306163 31643731343666353761633563633634326139396230313734333034653238303166

Ansibleがファイルの処理方法を知るために使用するいくつかのヘッダー情報と、それに続く数字として表示される暗号化されたコンテンツを見ることができます。

既存のファイルの暗号化

Vaultで暗号化するファイルがすでにある場合は、 ansible-vault encrypt 代わりにコマンド。

テストのために、次のように入力してサンプルファイルを作成できます。

  1. echo 'unencrypted stuff' > encrypt_me.txt

これで、次のように入力して既存のファイルを暗号化できます。

  1. ansible-vault encrypt encrypt_me.txt

ここでも、パスワードを入力して確認するように求められます。 その後、暗号化を確認するメッセージが表示されます。

Output
New Vault password: Confirm New Vault password: Encryption successful

編集ウィンドウを開く代わりに、 ansible-vault ファイルの内容を暗号化してディスクに書き戻し、暗号化されていないバージョンを置き換えます。

ファイルを確認すると、同様の暗号化されたパターンが表示されます。

  1. cat encrypt_me.txt
Output
$ANSIBLE_VAULT;1.1;AES256 66633936653834616130346436353865303665396430383430353366616263323161393639393136 3737316539353434666438373035653132383434303338640a396635313062386464306132313834 34313336313338623537333332356231386438666565616537616538653465333431306638643961 3636663633363562320a613661313966376361396336383864656632376134353039663662666437 39393639343966363565636161316339643033393132626639303332373339376664

ご覧のとおり、Ansibleは、新しいファイルを暗号化するのとほぼ同じ方法で既存のコンテンツを暗号化します。

暗号化されたファイルの表示

場合によっては、ボールトで暗号化されたファイルを編集したり、暗号化されていないファイルシステムに書き込んだりせずに、ファイルの内容を参照する必要があります。 The ansible-vault view コマンドは、ファイルの内容を標準出力に送ります。 デフォルトでは、これはコンテンツが端末に表示されることを意味します。

ボールト暗号化ファイルを次のコマンドに渡します。

  1. ansible-vault view vault.yml

ファイルのパスワードの入力を求められます。 入力に成功すると、内容が表示されます。

Output
Vault password: Secret information

ご覧のとおり、ファイルの内容の出力にはパスワードプロンプトが混在しています。 使用するときはこれを覚えておいてください ansible-vault view 自動化されたプロセスで。

暗号化されたファイルの編集

暗号化されたファイルを編集する必要がある場合は、 ansible-vault edit 指図:

  1. ansible-vault edit vault.yml

ファイルのパスワードの入力を求められます。 入力後、Ansibleはファイルを編集ウィンドウで開き、必要な変更を加えることができます。

保存すると、新しいコンテンツはファイルの暗号化パスワードを使用して再度暗号化され、ディスクに書き込まれます。

暗号化されたファイルを手動で復号化する

ボールト暗号化ファイルを復号化するには、 ansible-vault decrypt 指図。

注:機密データをプロジェクトリポジトリに誤ってコミットする可能性が高くなるため、 ansible-vault decrypt コマンドは、ファイルから暗号化を完全に削除する場合にのみ推奨されます。 ボールトで暗号化されたファイルを表示または編集する必要がある場合は、通常、 ansible-vault view また ansible-vault edit それぞれコマンド。

暗号化されたファイルの名前を渡します。

  1. ansible-vault decrypt vault.yml

ファイルの暗号化パスワードの入力を求められます。 正しいパスワードを入力すると、ファイルは復号化されます。

Output
Vault password: Decryption successful

ボールト暗号化の代わりにファイルを再度表示すると、ファイルの実際の内容が表示されます。

  1. cat vault.yml
Output
Secret information

これで、ファイルはディスク上で暗号化されなくなりました。 終了したら、機密情報を削除するか、ファイルを再暗号化してください。

暗号化されたファイルのパスワードの変更

暗号化されたファイルのパスワードを変更する必要がある場合は、 ansible-vault rekey 指図:

  1. ansible-vault rekey encrypt_me.txt

コマンドを入力すると、最初にファイルの現在のパスワードの入力を求められます。

Output
Vault password:

入力後、新しいボールトパスワードを選択して確認するように求められます。

Output
Vault password: New Vault password: Confirm New Vault password:

新しいパスワードを正常に確認すると、再暗号化プロセスが成功したことを示すメッセージが表示されます。

Output
Rekey successful

これで、新しいパスワードを使用してファイルにアクセスできるようになります。 古いパスワードは機能しなくなります。

Vaultで暗号化されたファイルでAnsibleを実行する

Vaultで機密情報を暗号化した後、Ansibleの従来のツールでファイルの使用を開始できます。 The ansibleansible-playbook どちらのコマンドも、正しいパスワードを指定してボールトで保護されたファイルを復号化する方法を知っています。 必要に応じて、これらのコマンドにパスワードを提供する方法はいくつかあります。

従うには、ボールトで暗号化されたファイルが必要になります。 次のように入力して作成できます。

  1. ansible-vault create secret_key

パスワードを選択して確認します。 必要なダミーコンテンツを入力します。

secret_key
confidential data

ファイルを保存して閉じます。

一時的なものを作成することもできます hosts インベントリとしてのファイル:

  1. nano hosts

Ansibleローカルホストだけを追加します。 後のステップに備えるために、 [database] グループ:

ホスト
[database]
localhost ansible_connection=local

終了したら、ファイルを保存して閉じます。

次に、を作成します ansible.cfg まだ存在しない場合は、現在のディレクトリにあるファイル:

  1. nano ansible.cfg

今のところ、追加するだけです [defaults] セクションとポイント作成したばかりのインベントリにAnsible:

ansible.cfg
[defaults]
inventory = ./hosts

準備ができたら、続行します。

インタラクティブプロンプトの使用

実行時にコンテンツを復号化する最も簡単な方法は、Ansibleに適切なクレデンシャルの入力を求めるプロンプトを表示させることです。 これを行うには、 --ask-vault-passansible また ansible-playbook 指図。 Ansibleは、ボールトで保護されたコンテンツを見つけた場合に復号化するために使用するパスワードの入力を求めます。

たとえば、ボールトで暗号化されたファイルの内容をホストにコピーする必要がある場合は、 copy モジュールと --ask-vault-pass 国旗。 ファイルに実際に機密データが含まれている場合は、アクセス許可と所有権の制限を使用して、リモートホストへのアクセスをロックダウンすることをお勧めします。

注:使用しています localhost この例では、必要なサーバーの数を最小限に抑えるためのターゲットホストとして使用しますが、結果は、ホストが本当にリモートである場合と同じになるはずです。

  1. ansible --ask-vault-pass -bK -m copy -a 'src=secret_key dest=/tmp/secret_key mode=0600 owner=root group=root' localhost

このタスクでは、ファイルの所有権を次のように変更する必要があることを指定しています root、したがって、管理者権限が必要です。 The -bK フラグはAnsibleにプロンプトを表示するように指示します sudo ターゲットホストのパスワード。 sudo パスワード。 次に、Vaultのパスワードの入力を求められます。

Output
BECOME password: Vault password:

パスワードが提供されると、Ansibleは、検出した暗号化ファイルにVaultパスワードを使用して、タスクの実行を試みます。 実行中に参照されるすべてのファイルは同じパスワードを使用する必要があることに注意してください。

Output
localhost | SUCCESS => { "changed": true, "checksum": "7a2eb5528c44877da9b0250710cba321bc6dac2d", "dest": "/tmp/secret_key", "gid": 0, "group": "root", "md5sum": "270ac7da333dd1db7d5f7d8307bd6b41", "mode": "0600", "owner": "root", "size": 18, "src": "/home/sammy/.ansible/tmp/ansible-tmp-1480978964.81-196645606972905/source", "state": "file", "uid": 0 }

パスワードの入力を求めることは安全ですが、特に繰り返し実行する場合は面倒であり、自動化の妨げにもなります。 ありがたいことに、これらの状況にはいくつかの選択肢があります。

パスワードファイルでのAnsibleVaultの使用

タスクを実行するたびにVaultパスワードを入力したくない場合は、Vaultパスワードをファイルに追加して、実行中にファイルを参照できます。

たとえば、パスワードを .vault_pass このようなファイル:

  1. echo 'my_vault_password' > .vault_pass

バージョン管理を使用している場合は、誤ってコミットしないように、バージョン管理ソフトウェアの無視ファイルにパスワードファイルを追加してください。

  1. echo '.vault_pass' >> .gitignore

これで、代わりにファイルを参照できます。 The --vault-password-file フラグはコマンドラインで使用できます。 次のように入力することで、前のセクションと同じタスクを完了することができます。

  1. ansible --vault-password-file=.vault_pass -bK -m copy -a 'src=secret_key dest=/tmp/secret_key mode=0600 owner=root group=root' localhost

今回は、Vaultパスワードの入力を求められることはありません。

Output
localhost | SUCCESS => { "changed": false, "checksum": "52d7a243aea83e6b0e478db55a2554a8530358b0", "dest": "/tmp/secret_key", "gid": 80, "group": "root", "mode": "0600", "owner": "root", "path": "/tmp/secret_key", "size": 8, "state": "file", "uid": 0 }

パスワードファイルの自動読み取り

フラグをまったく提供する必要がないように、次のように設定できます。 ANSIBLE_VAULT_PASSWORD_FILE パスワードファイルへのパスを持つ環境変数:

  1. export ANSIBLE_VAULT_PASSWORD_FILE=./.vault_pass

これで、コマンドを実行しなくてもコマンドを実行できるようになります。 --vault-password-file 現在のセッションのフラグ:

  1. ansible -bK -m copy -a 'src=secret_key dest=/tmp/secret_key mode=0600 owner=root group=root' localhost

Ansibleにセッション間でのパスワードファイルの場所を認識させるために、 ansible.cfg ファイル。

ローカルを開く ansible.cfg 以前に作成したファイル:

  1. nano ansible.cfg

の中に [defaults] セクション、を設定します vault_password_file 設定。 パスワードファイルの場所をポイントします。 これは、どちらが最も役立つかに応じて、相対パスまたは絶対パスにすることができます。

ansible.cfg
[defaults]
. . .
vault_password_file = ./.vault_pass

これで、復号化が必要なコマンドを実行するときに、ボールトパスワードの入力を求められなくなりました。 ボーナスとして、 ansible-vault ファイル内のパスワードを使用してファイルを復号化するだけでなく、で新しいファイルを作成するときにパスワードを適用します ansible-vault createansible-vault encrypt.

環境変数からのパスワードの読み取り

パスワードファイルを誤ってリポジトリにコミットすることを心配するかもしれません。 Ansibleにはパスワードファイルの場所を指す環境変数がありますが、パスワード自体を設定するための環境変数はありません。

ただし、パスワードファイルが実行可能である場合、Ansibleはそれをスクリプトとして実行し、結果の出力をパスワードとして使用します。 GitHubの問題で、 Brian Schwind は、次のスクリプトを使用して環境変数からパスワードを取得できることを示唆しています。

あなたの .vault_pass エディター内のファイル:

  1. nano .vault_pass

内容を次のスクリプトに置き換えます。

.vault_pass
#!/usr/bin/env python3

import os
print os.environ['VAULT_PASSWORD']

次のように入力して、ファイルを実行可能にします。

  1. chmod +x .vault_pass

その後、設定してエクスポートできます VAULT_PASSWORD 現在のセッションで使用できる環境変数:

export VAULT_PASSWORD=my_vault_password

これは、各Ansibleセッションの開始時に行う必要があり、不便に聞こえるかもしれません。 ただし、これにより、Vault暗号化パスワードを誤ってコミットすることを効果的に防ぐことができます。これは重大な欠点をもたらす可能性があります。

Vaultで暗号化された変数を通常の変数で使用する

Ansible Vaultは任意のファイルで使用できますが、機密性の高い変数を保護するために最も頻繁に使用されます。 例を使用して、通常の変数ファイルをセキュリティと使いやすさのバランスが取れた構成に変換する方法を示します。

例の設定

この例では、前提条件としてデータベースを実際にインストールする必要なしに、データベースサーバーを構成しているように見せかけます。

作成したとき hosts 以前にファイルを配置しました localhost と呼ばれるグループのエントリ database このステップの準備をします。 データベースには通常、機密性の高い変数と機密性の低い変数が混在している必要があります。 これらはで割り当てることができます group_vars グループにちなんで名付けられたファイル内のディレクトリ:

  1. mkdir -p group_vars
  2. nano group_vars/database

内部 group_vars/database ファイル、いくつかの典型的な変数を追加します。 MySQLポート番号などの一部の変数は秘密ではなく、自由に共有できます。 データベースパスワードなどの他の変数は機密扱いになります。

group_vars / database
---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred

# sensitive data
mysql_password: supersecretpassword

Ansibleを使用して、すべての変数がホストで利用可能であることをテストできます。 debug モジュールと hostvars 変数:

  1. ansible -m debug -a 'var=hostvars[inventory_hostname]' database
Output
localhost | SUCCESS => { "hostvars[inventory_hostname]": { "ansible_check_mode": false, "ansible_version": { "full": "2.2.0.0", "major": 2, "minor": 2, "revision": 0, "string": "2.2.0.0" }, "group_names": [ "database" ], "groups": { "all": [ "localhost" ], "database": [ "localhost" ], "ungrouped": [] }, "inventory_dir": "/home/sammy", "inventory_file": "hosts", "inventory_hostname": "localhost", "inventory_hostname_short": "localhost", "mysql_host": "10.0.0.3", "mysql_password": "supersecretpassword", "mysql_port": 3306, "mysql_user": "fred", "omit": "__omit_place_holder__1c934a5a224ca1d235ff05eb9bda22044a6fb400", "playbook_dir": "." } }

出力は、設定したすべての変数がホストに適用されていることを確認します。 しかし、私たちの group_vars/database ファイルは現在、すべての変数を保持しています。 これは、データベースのパスワード変数のためにセキュリティ上の懸念がある暗号化されないままにするか、すべての変数を暗号化することで、使いやすさとコラボレーションの問題を引き起こす可能性があることを意味します。

機密変数をAnsibleVaultに移動する

この問題を解決するには、機密変数と非機密変数を区別する必要があります。 機密値を暗号化すると同時に、機密性の低い変数を簡単に共有できる必要があります。 そのために、変数を2つのファイルに分割します。

複数のファイルから変数を適用するために、Ansible変数fileの代わりに変数directoryを使用することができます。 その機能を利用するために、構成をリファクタリングできます。 まず、既存のファイルの名前を databasevars. これは、暗号化されていない変数ファイルになります。

  1. mv group_vars/database group_vars/vars

次に、古い変数ファイルと同じ名前のディレクトリを作成します。 移動します vars 内部のファイル:

  1. mkdir group_vars/database
  2. mv group_vars/vars group_vars/database/

これで、 database 単一のファイルの代わりにグループを作成すると、暗号化されていない変数ファイルが1つあります。 機密変数を暗号化するので、暗号化されていないファイルからそれらを削除する必要があります。 編集します group_vars/database/vars 機密データを削除するファイル:

  1. nano group_vars/database/vars

この場合、削除したい mysql_password 変数。 ファイルは次のようになります。

group_vars / database / vars
---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred

次に、暗号化されていないファイルと一緒に存在するディレクトリ内にボールト暗号化されたファイルを作成します vars ファイル:

  1. ansible-vault create group_vars/database/vault

このファイルで、以前は vars ファイル。 同じ変数名を使用しますが、文字列を先頭に追加します vault_ これらの変数がボールトで保護されたファイルで定義されていることを示すには、次のようにします。

group_vars / database / vault
---
vault_mysql_password: supersecretpassword

終了したら、ファイルを保存して閉じます。

結果のディレクトリ構造は次のようになります。

.
├── . . .
├── group_vars/
│   └── database/
│       ├── vars
│       └── vault
└── . . .

この時点で、変数は分離され、機密データのみが暗号化されます。 これは安全ですが、私たちの実装は私たちの使いやすさに影響を与えました。 私たちの目標は機密性の高いを保護することでしたが、実際の変数名の可視性も意図せずに低下させました。 複数のファイルを参照せずにどの変数が割り当てられるかは明確ではありません。共同作業中に機密データへのアクセスを制限したい場合でも、変数名を共有したい場合があります。

これに対処するために、Ansibleプロジェクトは通常、わずかに異なるアプローチを推奨しています。

暗号化されていない変数からのVault変数の参照

機密データをボールトで保護されたファイルに移動するとき、変数名の前に vault_ (mysql_password なりました vault_mysql_password). 元の変数名を追加できます(mysql_password)暗号化されていないファイルに戻ります。 これらを機密値に直接設定する代わりに、Jinja2テンプレートステートメントを使用して、暗号化されていない変数ファイル内から暗号化された変数名を参照できます。 このように、単一のファイルを参照することで定義されたすべての変数を確認できますが、機密値は暗号化されたファイルに残ります。

実例を示すために、暗号化されていない変数ファイルをもう一度開きます。

  1. nano group_vars/database/vars

追加します mysql_password 再び変数。 今回は、Jinja2テンプレートを使用して、ボールトで保護されたファイルで定義された変数を参照します。

group_vars / database / vars
---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred

# sensitive data
mysql_password: "{{ vault_mysql_password }}"

The mysql_password 変数はの値に設定されます vault_mysql_password ボールトファイルで定義されている変数。

この方法を使用すると、ホストに適用されるすべての変数を理解できます。 database グループを表示して group_vars/database/vars ファイル。 敏感な部分は、Jinja2のテンプレートによって隠されます。 The group_vars/database/vault 値自体を表示または変更する必要がある場合にのみ開く必要があります。

あなたはすべてが mysql_* 変数は、前回と同じ方法を使用して正しく適用されます。

注: Vaultのパスワードがパスワードファイルに自動的に適用されない場合は、 --ask-vault-pass 以下のコマンドにフラグを立てます。

  1. ansible -m debug -a 'var=hostvars[inventory_hostname]' database
Output
localhost | SUCCESS => { "hostvars[inventory_hostname]": { "ansible_check_mode": false, "ansible_version": { "full": "2.2.0.0", "major": 2, "minor": 2, "revision": 0, "string": "2.2.0.0" }, "group_names": [ "database" ], "groups": { "all": [ "localhost" ], "database": [ "localhost" ], "ungrouped": [] }, "inventory_dir": "/home/sammy/vault", "inventory_file": "./hosts", "inventory_hostname": "localhost", "inventory_hostname_short": "localhost", "mysql_host": "10.0.0.3", "mysql_password": "supersecretpassword", "mysql_port": 3306, "mysql_user": "fred", "omit": "__omit_place_holder__6dd15dda7eddafe98b6226226c7298934f666fc8", "playbook_dir": ".", "vault_mysql_password": "supersecretpassword" } }

両方 vault_mysql_password そしてその mysql_password アクセス可能です。 この複製は無害であり、このシステムの使用に影響を与えることはありません。

結論

プロジェクトには、複雑なシステムを正常にインストールおよび構成するために必要なすべての情報が含まれている必要があります。 ただし、一部の構成データは定義上機密性が高く、公開すべきではありません。 このガイドでは、セキュリティを損なうことなくすべての構成データを1つの場所に保持できるように、AnsibleVaultが機密情報を暗号化する方法を示しました。