こんにちは、インフラ担当の天津です。今日はAnsibleでの小ネタをご紹介します。
TL;DR
roleごとにユーザを切り替えが可能かを調べ、可能であることを確認しました。
モチベーション
ユーザ作成とそのユーザでの構築作業を実施したいことがありましたので調べました。
例えば下記のようの状況です。
- ec2-userで接続
- rootでansible実行用ユーザを作成
- 以降の処理はansible実行用ユーザで実施する
やってみた
マニュアルを読む
公式マニュアルを参照します。
https://docs.ansible.com/ansible/latest/user_guide/become.html
変数を指定することで設定できそうです。
実装してみる
一回目
下記のようなplaybookを作成してみました。
ansible実行用ユーザをwheelグループに作成します。
パスワードやssh公開鍵も設定します。(値は適当なものです)
sample-playbook.yml
- hosts: sample roles: - role: adduser vars: - ansible_become: yes - ansible_become_user: root - uid: 444 - pub_key: hogehoge - role: test-role vars: - ansible_become: yes - ansible_become_user: ansible
roles/adduser/tasks/main.yml
-- - name: user create user: name: ansible group: wheel system: yes uid: {{uid}} password: "hogehoge" - name: set authorized_keys authorized_key: user: ansible state: present key: {{pub_key}}
test-role/tasks/main.yml
--- # tasks file for test-role - name: setup setup: - name: sample shell: echo `id`
ロールはadduserとtest-roleです。
adduserロールでansible実行用ユーザを作成し、test-roleはidコマンドの結果をechoするものです。
EC2を対象にして、動かしてみましょう。
$ ansible-playbook --private-key ~/.ssh/hoge.pem -u ec2-user -i inventory/production sample-playbook.yml -v
PLAY [sample] ******************************************************************************************************************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************************** fatal: [ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com]: FAILED! => {"msg": "Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: 1, err: chown: ユーザ指定が不正: `ansible'\n}). For information on working around this, see https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user"} PLAY RECAP *********************************************************************************************************************************************************************************************************************************** ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com : ok=0 changed=0 unreachable=0 failed=1
Gathering Factsでエラーになりました。
ユーザ指定が不正と言われています。
これは存在しないユーザをbecome_userで指定しているからと思われます。
二回目
ではGathering Factsをオフにしてみましょう。
sample-playbook.yml
- hosts: sample gather_facts: no roles: - role: adduser vars: - ansible_become: yes - ansible_become_user: root - uid: 444 - pub_key: "ssh-rsa hogehoge" - role: test-role vars: - ansible_become: yes - ansible_become_user: ansible
実行してみます。
$ ansible-playbook --private-key ~/.ssh/hoge.pem -u ec2-user -i inventory/production sample-playbook.yml -v
PLAY [sample] ******************************************************************************************************************************************************************************************************************************** TASK [adduser : user create] ***************************************************************************************************************************************************************************************************************** changed: [ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com] => {"changed": true, "comment": "", "create_home": true, "group": 10, "home": "/home/ansible", "name": "ansible", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": true, "uid": 444} TASK [adduser : set authorized_keys] *********************************************************************************************************************************************************************************************************changed: [ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com] => {"changed": true, "comment": null, "exclusive": false, "follow": false, "key": "ssh-rsa hogehoge", "key_options": null, "keyfile": "/home/ansible/.ssh/authorized_keys", "manage_dir": true, "path": null, "state": "present", "unique": false, "user": "ansible", "validate_certs": true} TASK [test-role : sample] ******************************************************************************************************************************************************************************************************************** [WARNING]: Module remote_tmp /home/ansible/.ansible/tmp did not exist and was created with a mode of 0700, this may cause issues when running as another user. To avoid this, create the remote_tmp dir with the correct permissions manually changed: [ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com] => {"changed": true, "cmd": "echo `id`", "delta": "0:00:00.003924", "end": "2018-11-20 02:24:54.110334", "rc": 0, "start": "2018-11-20 02:24:54.106410", "stderr": "", "stderr_lines": [], "stdout": "uid=444(ansible) gid=10(wheel) groups=10(wheel)", "stdout_lines": ["uid=444(ansible) gid=10(wheel) groups=10(wheel)"]} PLAY RECAP *********************************************************************************************************************************************************************************************************************************** ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com : ok=4 changed=3 unreachable=0 failed=0
最後まで実行されましたがWARNINGが出てしまいました。
Ansibleは実行先にマシンにスクリプトファイルを送って実行するのでその際の置き場所が無いので出ています。
解決策としては下記がありますが、今回はそのままとします。
- remote_tmpで作成しておく
- 初回のみなので何もしない
さて、これで終わりかと思いますが、このままですとfactsを使用できない状態です。
三回目
factsをとるロールを追加してみましょう。
fact-role/tasks/main.yml
--- # tasks file for fact-role - name: setup setup:
setupモジュールを呼ぶだけです。
roleをplaybookに追加します。
sample-playbook.yml
- hosts: sample gather_facts: no roles: - role: adduser vars: - ansible_become: yes - ansible_become_user: root - uid: 444 - pub_key: "ssh-rsa hogehoge" - role: fact-role vars: - ansible_become: yes - ansible_become_user: root - role: test-role vars: - ansible_become: yes - ansible_become_user: ansible
PLAY [sample] ******************************************************************************************************************************************************************************************************************************** TASK [adduser : user create] ***************************************************************************************************************************************************************************************************************** changed: [ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com] => {"changed": true, "comment": "", "create_home": true, "group": 10, "home": "/home/ansible", "name": "ansible", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": true, "uid": 444} TASK [adduser : set authorized_keys] ********************************************************************************************************************************************************************************************************* changed: [ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com] => {"changed": true, "comment": null, "exclusive": false, "follow": false, "key": "ssh-rsa hogehoge", "key_options": null, "keyfile": "/home/ansible/.ssh/authorized_keys", "manage_dir": true, "path": null, "state": "present", "unique": false, "user": "ansible", "validate_certs": true} TASK [fact-role : setup] ********************************************************************************************************************************************************************************************************************* ok: [ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com] TASK [test-role : sample] ******************************************************************************************************************************************************************************************************************** [WARNING]: Module remote_tmp /home/ansible/.ansible/tmp did not exist and was created with a mode of 0700, this may cause issues when running as another user. To avoid this, create the remote_tmp dir with the correct permissions manually changed: [ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com] => {"changed": true, "cmd": "echo `id`", "delta": "0:00:00.003836", "end": "2018-11-20 02:38:43.022517", "rc": 0, "start": "2018-11-20 02:38:43.018681", "stderr": "", "stderr_lines": [], "stdout": "uid=444(ansible) gid=10(wheel) groups=10(wheel)", "stdout_lines": ["uid=444(ansible) gid=10(wheel) groups=10(wheel)"]} PLAY RECAP *********************************************************************************************************************************************************************************************************************************** ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com : ok=4 changed=3 unreachable=0 failed=0
WARNINGは出ていますが、無事factsも取得できました。
まとめ
Ansibleでのroleごとのユーザ使い分けを試してみましたが、意外と簡単にできました。
varsに指定できるので、playbookではなくhost_vars/group_varsで指定したり、roleのdefaultに指定もできますね。
最後までお読みいただき有難うございました。