Ansible Vaultで異なるパスワードを用いたファイル暗号化

Ansbile 2.4からAnsbile Vaultで複数IDを使い、異なるパスワードを設定できるようになっておりますので、
2つの異なるパスワードで暗号化した変数ファイルと暗号化を行わない変数ファイルを1つ用意したRoleの検証を行ってみます。

2つの暗号化したパスワードファイルを使ったroleの実行

Ansible用ユーザを作成するPlaybookを作成(ユーザパスワードを暗号化、SSHログイン・sudoパスワードの暗号化)

次にAnsible用の実行ユーザを各サーバに用意するロールを作成してみます。
その1で作成したtest1ユーザを使用します。
想定はサーバ構築者にsudoできるユーザをパスワードログインで一時的に作ってもらい
そこからAnsbileの実行ユーザを作成するシナリオになります。

$ cd /opt/ansible
$ ansible-galaxy init --offline op_user_add
$ tree op_user_add
op_user_add
├── README.md
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
└── main.yml

varsのmain.ymlがあるとmainディレクトリを読み込まないため削除します。

$ cd op_user_add
$ rm -rf vars/main.yml

複数の変数ファイルを読み込むようmainディレクトリを作成します。

$ mkdir vars/main

暗号化しない変数ファイルを作成します。
このときvars/main/main.ymlにしますと実行時vars/main.ymlが必要というエラーになりますので
それ以外の名前にして下さい。

$ vi vars/main/vars.yml
user: ansible
group: automation

作成ユーザのパスワードが入った変数ファイルを作成します。

$ vi vars/main/op_pass.yml
pass: hoge1234

ログインユーザのパスワードが入った変数ファイルを作成します。

$ vi vars/main/test1_pass.yml
ansible_ssh_pass: hogehoge
ansible_sudo_pass: hogehoge

暗号化用のパスワードを記載します。

$ mkdir /opt/ansible/.ssh
$ vi /opt/ansible/.ssh/op_pass
$ vi /opt/ansible/.ssh/test1_pass

ansible-vaultでop_pass.ymlで暗号化します。
ansible.cfgがあるとエラーになることがありますので
その際はansible.cfgを先に削除下さい。

$ (rm -rf ansible.cfg)
$ ansible-vault encrypt --vault-id op@/opt/ansible/.ssh/op_pass vars/main/op_pass.yml
$ ansible-vault encrypt --vault-id test1@/opt/ansible/.ssh/test1_pass vars/main/test1_pass.yml

SSHの公開鍵を配置します。
これは直後のtasks/main.ymlで指定する箇所になりますので注意下さい。
権限も気をつける必要があります。

sudoが可能なユーザを作成します。
また、sudoができるようディストリビューションごとに異なる
グループに所属させます。
パスワードなしでログインできるように鍵も配布します。
また、ログが表示できるようhandlerで捕捉します。
特にエラー処理していないため実行ごとにパスワードハッシュが変わり常にchangedになります。

$ vi tasks/main.yml
---
# tasks file for test
- name: Create Group
  group:
    name: "{{group}}"

- name: RedHat Create User
  user:
    name: "{{user}}"
    password: "{{ pass | password_hash('sha512') }}"
    group: "{{group}}"
    groups:  wheel
    shell: /bin/bash
  when:
  - ansible_distribution != "Ubuntu"
  - ansible_distribution != "Debian"

- name: Debian Ubuntu Create User
  user:
    name: "{{user}}"
    password: "{{ pass | password_hash('sha512') }}"
    group: "{{group}}"
    groups:  adm
    shell: /bin/bash
  when:
  - ansible_distribution == "Ubuntu" or ansible_distribution == "Debian"

- name: .ssh Directory Create
  file:
    path: "/home/{{user}}/.ssh"
    state: directory
    owner: "{{user}}"
    group: "{{group}}"
    mode: "700"

- name: Add AuthKey
  ansible.posix.authorized_key:
    user: "{{ user }}"
    key: "{{ lookup('file', '/home/xxxxx/.ssh/id_rsa.pub') }}"

- name: User Check
  command: "id '{{user}}'"
  notify: handler
  register: result

ハンドラーを記載します。

$ vi handlers/main.yml
---
# handlers file for test
- name: handler
  debug: var="result"

インベントリを記載します。

$ vi inventory
[RHEL]
localhost
[CentOS]
192.168.1.55
[Alma]
192.168.1.56
192.168.1.57
[Rocky]
192.168.1.58
192.168.1.59
[Ubuntu]
192.168.1.50
192.168.1.51
192.168.1.52
[Debian]
192.168.1.53
192.168.1.54

ansible.posix.authorized_keyを使うためにAnsible Collectionを通じて導入します。

$ ansible-galaxy collection install ansible.posix

ロールを実行するプレイブックを記載します。

$ cd ../
$ vi useradd.yml
---
- name: test
  hosts: all
  user: test1
  become: true
  gather_facts: true

  roles:
  - op_user_add

ansible.cfgを作成します。

vi ansible.cfg
[defaults]
vault_identity_list = op@/opt/ansible/.ssh/op_pass,test1@/opt/ansible/.ssh/test1_pass
vault_id_match = true

Ansible用ユーザを作成するPlaybookを実行(パスワードを平文格納、sudoパスワード不要)

実行します。これでAnsbile用の実行ユーザが作成されます。

$ ansible-playbook useradd.yml -i op_user_add/inventory

ファイル構成

今回実行時のファイル構成はこのようになっております。

$ tree ./
./
├── ansible.cfg(
├── op_user_add
│ ├── README.md
│ ├── defaults
│ │  └── main.yml
│ ├── files
│ ├── handlers
│ │  └── main.yml
│ ├── inventory
│ ├── meta
│ │  └── main.yml
│ ├── tasks
│ │  └── main.yml
│ ├── templates
│ ├── tests
│ │  ├── inventory
│ │  └── test.yml
│ └── vars
│     └── main
│         ├── op_pass.yml(vault-id:opで暗号化したファイル)
│         ├── test1_pass.yml(vault-id:test1で暗号化したファイル)
│         └── vars.yml(通常の変数ファイル)
├──useradd.yml(ロール実行用)

一時的に作成されたユーザの削除

その1で作成されたユーザなので同じ設定ファイルを使って削除します。
まず、プレイブックをバックアップします。

$ mv test/tasks/main.yml test/tasks/old.yml

test1を削除するプレイブックを作成します。

$ vi test/tasks/main.yml
---
# tasks file for test
- name: Delete User
  user:
    user: test1
    state: absent
    remove: yes
  notify: handler
  register: result

暗号化済みのymlを削除して、実行します。

$ rm -rf test/vars/main/sudo_pass.yml
$ ansible-playbook test.yml -i test/inventory