前回「Ansible のインストールと管理対象サーバへの接続設定メモ」の記事では、root ユーザ+パスワード認証でAnsibleを実行しましたが、「rootユーザでのリモートログイン」や「パスワード認証」は、セキュリティポリシーで禁止されている場合もあるかと思います。そこで今回は、Ansibleで、Ansible実行用のユーザを作成し、SSH公開鍵の登録とsudo権限を付与する Playbook を作成してみました。
Playbook と YAMLフォーマット
Ansibleでは、構成手順が書かれたファイルを「Playbook(プレイブック)」と呼び、Playbookは、構造化されたデータを表現するための YMAL(「ヤムル」と読むことが多いようです)というフォーマットで書きます。そのため、Playbookの拡張子は「.yml」になります。
YAMLは、「人に読みやすい」ことを目指して開発されているため、データ構造をインデントを使って表現するのが特徴です。YAMLは構文チェックをしっかりやってくれるので、以下の点に気をつけると良いでしょう。
- インデントの縦を合わせる(インデント幅は慣習的にスペース2つ)
- キーと値の区切り文字「:」の後ろは必ず空ける(× name:foo、○ name: foo)
- 構文エラーになる場合は、クォートしてみる
YAML Syntax | Ansible Documentation
YAML Ain’t Markup Language
SSH鍵ペアの作成
下準備として、Ansible管理ホストでSSH鍵ペアを生成します。この鍵ペアのうちSSH公開鍵(id_rsa.pub)を、Ansibleで管理対象サーバに登録します。
(略)
Generating public/private rsa key pair.
Enter file in which to save the key (/home/foo/.ssh/id_rsa): <空エンター>
Created directory '/home/foo/.ssh'.
Enter passphrase (empty for no passphrase): <パスフレーズ>
Enter same passphrase again: <パスフレーズ>
(略)
ユーザ追加 Playbook の作成
管理対象サーバに、Linuxユーザを追加するための Playbook を作成します。
処理対象ホストの指定
vi /etc/ansible/adduser-ansible.yml
--- - hosts: 172.16.1.111 tasks:
---
YAMLフォーマットのファイルは、慣習的に「---」(ハイフン3つ)から始めます。
- hosts:
処理対象のホストを指定します。ホストのIPアドレスまたはFQDNが、インベントリファイル「/etc/ansible/hosts」に、記載されている必要があります。
tasks:
この下に実行したいタスク(処理)を書いていきます。
Working with playbooks | Ansible Documentation
ユーザの作成
- name: ansible ユーザの作成 user: name=ansible uid=1001
- name:
タスクの簡単な説明を書きます。(これはどのタスクでも共通です)
user:
userモジュールを使って、ユーザを作成します。
name=
ユーザ名を指定。今回は、ユーザ名を ansible としましたが、なんでも構いません。
uid=
UIDを指定(任意です)多数のサーバを管理する場合は指定することをオススメします。これを指定しない場合、サーバAのfooユーザのUIDは「1002」、でもサーバBのfooユーザのUIDは「1003」ということが起こりえます。
ユーザの作成(パスワードを設定する場合)
今回は、公開鍵認証を使うため、上の例ではパスワードを指定していませんが、パスワード認証を使う場合は、ハッシュ化したパスワードを「password」オプションに指定します。
Pythonのパスワードハッシュ化ライブラリをインストールします。
一行で書くと長くなるので、マッピング構造(連想配列のようなもの)で書きました。
user: name: ansible uid: 1001 password: "{{ '<パスワード>' | password_hash('sha512') }}"
SSH公開鍵の登録
- name: Ansible管理ホストのSSH公開鍵を登録 authorized_key: user: ansible key: "{{ lookup('file', '/root/.ssh/id_rsa.pub') }}"
authorized_key:
authorized_keyモジュールを使って、SSH公開鍵を登録します。
user:
ここで指定した管理対象サーバ上のユーザ(今回の場合は ansible)の authorized_keys ファイルにSSH公開鍵を登録します。
key:
登録するSSH公開鍵を指定します。「lookup('file', '/home/foo/.ssh/id_rsa.pub')」は「cat /home/foo/.ssh/id_rsa.pub」と同義です。
sudo 権限の付与
- name: ansible ユーザに sudo 権限を付与 lineinfile: dest: /etc/sudoers backup: yes line: 'ansible ALL=(ALL) NOPASSWD: ALL'
lineinfile:
lineinfileモジュールを使って、sudoersファイルを編集します。
dest:
編集するファイルのパスを指定
backup:
yes を指定すると、編集前のファイルをバックアップしてくれます。
line:
追記する文字列を指定します。
完成した Playbook
以上でPlaybookの完成です。まとめると下記のようになります。
vi /etc/ansible/adduser-ansible.yml
--- - hosts: 172.16.1.111 tasks: - name: ansible ユーザの作成 user: name=ansible uid=1001 - name: Ansible管理ホストのSSH公開鍵を登録 authorized_key: user: ansible key: "{{ lookup('file', '/home/foo/.ssh/id_rsa.pub') }}" - name: ansible ユーザに sudo 権限を付与 lineinfile: dest: /etc/sudoers backup: yes line: 'ansible ALL=(ALL) NOPASSWD: ALL'
Playbook の動作テスト
作成した Playbook が正しく動作するかテストしてみます。
構文チェック
Playbook を「--syntax-check」オプションを指定して実行します。なにもエラーが表示されなければOKです。
ansible-playbook adduser-ansible.yml --syntax-check
playbook: adduser-ansible.yml
構文に誤りがある場合は、以下のようなエラーが表示されます。(下の場合はインデントがズレているため構文エラーになっています)
ERROR! Syntax Error while loading YAML. The error appears to have been in '/etc/ansible/adduser-ansible.yml': line 5, column 12, but may be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: - name: ansible ユーザの作成 user: name=ansible uid=1001 ^ here
Dry Run(ドライラン)
Playbook を「--check(または -C)」オプションを付けて実行すると、実際には変更を加えない「Dry Run」モードで動作します。ただし、今回作成したPlaybookのように、前後のタスクに依存関係がある場合はエラーになります。
実際にはansibleユーザが作成されていないため、SSH公開鍵が登録できずエラーになっています。
(略) TASK [ansible ユーザの作成] ********************************************************** changed: [172.16.1.111] TASK [Ansible管理ホストのSSH公開鍵を登録] ************************************************** fatal: [172.16.1.111]: FAILED! => {"changed": false, "failed": true, "msg": "Either user must exist or you must provide full path to key file in check mode"}
Check Mode (“Dry Run”) | Ansible Documentation
Playbook の実行
いよいよ作成した Playbook の実行です。
-u SSH接続に使うユーザを指定
-k 接続パスワードの入力を求める
以下のような表示であれば成功です。
PLAY [172.16.1.111] ********************************************************** TASK [setup] ******************************************************************* ok: [172.16.1.111] TASK [ansible ユーザの作成] ********************************************************** changed: [172.16.1.111] TASK [Ansible管理ホストのSSH公開鍵を登録] ************************************************** changed: [172.16.1.111] TASK [ansible ユーザに sudo 権限を付与] ************************************************* changed: [172.16.1.111] PLAY RECAP ********************************************************************* 172.16.1.111 : ok=4 changed=3 unreachable=0 failed=0
作成したユーザで、管理対象サーバに接続できることが確認できると思います。
Enter passphrase for key '/home/foo/.ssh/id_rsa':<パスフレーズ>
172.16.1.111 | SUCCESS => {
"changed": false,
"ping": "pong"
}
終わりに
次回は、Ansible で Playbook を分割してモジュール化する仕組み「Roles」についてまとめてみたいと思います。
コメント
とても参考になりました