こんにちは、インフラ担当の天津です。今日は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に指定もできますね。
最後までお読みいただき有難うございました。