** Features of Ansible ** --It is a tool that automates server construction without agents. --It connects to the machine running sshd with SSH and builds the environment. --Write the configuration file in YAML. No programming knowledge (Ruby, Python, etc.) is required. --It's easier than chef to build a few to dozens of servers.
** Preparing the environment ** See previous article. Ansible First Step
Starting with Ansible 1.9,'become' has been added to run with other user privileges (eg root privileges).
If you want to manage a server that is prohibited from direct access as root, you should log in as a general user and then use sudo su -
to become root.
When executing a command with become: ture
in Ansible, and when executing a command directly from the command line after sudo su -
, the command execution result may differ because the PATH environment variable is different. Yes, you need to be careful.
Until now, I used this area without much awareness, so the command that was confirmed by directly executing the command sometimes failed in PlayBook, so I had a little trouble, so about become
and the environment variable PATH, I checked it again.
become: true
≠ sudo su -
".sudo su -
.I investigated the issues on GitHub, the official website of Ansible.
Only one method may be enabled per host
Methods cannot be chained. You cannot use
sudo /bin/su -
to become a user, you need to have privileges to run the command as that user in sudo or be able to su directly to it.
Free translation:
sudo
andsu
cannot be used at the same time, so if you want to usesudo su -
, execute the command directly.
Ansible GitHub issues It seems that the discussion at the head family has not reached a conclusion (the status remains Open). GitHub issues#12686
First, I investigated what the PATH would look like. Survey environment: Amazon Linux AMI 2016.03
remote_user: ec2-user
1. become: false(ec2-user) /usr/local/bin:/bin:/usr/bin:/opt/aws/bin 2. become: true(root) /sbin:/bin:/usr/sbin:/usr/bin 3. lookup('pipe', 'echo $PATH') /usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin: /sbin:/opt/aws/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin 4. lookup('env', 'PATH') /usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin: /sbin:/opt/aws/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin 5. ec2-user /usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin: /sbin:/opt/aws/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin 6. sudo su - /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin: /opt/aws/bin:/root/bin 7. sudo su /sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin
It's splendidly disjointed ^^;
A Google search will show you how to read .bashrc and .bash_profile with command and shell, but doing so makes it difficult to guarantee idempotency. Therefore, I will introduce how to set the PATH in the environment.
First, let's see what happens if nothing is done.
playbook.yml
- hosts: all
remote_user: ec2-user
tasks:
- command: echo $PATH
register: become_path
become: true
changed_when: False
- name: become
debug: var=become_path.stdout
- command: echo $PATH
register: not_become_path
changed_when: False
- name: not become
debug: var=not_become_path.stdout
I will try it.
$ ansible-playbook env_path.yml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [target03]
TASK [command] *****************************************************************
ok: [target03]
TASK [become] ******************************************************************
ok: [target03] => {
"become_path.stdout": "/sbin:/bin:/usr/sbin:/usr/bin"
}
TASK [command] *****************************************************************
ok: [target03]
TASK [not become] **************************************************************
ok: [target03] => {
"not_become_path.stdout": "/usr/local/bin:/bin:/usr/bin:/opt/aws/bin"
}
PLAY RECAP *********************************************************************
target03 : ok=5 changed=0 unreachable=0 failed=0
General user PATH: / usr / local / bin: / bin: / usr / bin: / opt / aws / bin
root PATH: / sbin: / bin: / usr / sbin: / usr / bin
It has become. It seems that you are not logged in.
If you use lookup, it will be as follows.
playbook.yml
---
- hosts: all
remote_user: ec2-user
vars:
pipe_path: "{{ lookup('pipe', 'echo $PATH') }}"
env_path: "{{ lookup('env', 'PATH') }}"
tasks:
- name: pipe path
debug: msg={{ pipe_path }}
- name: env path
debug: msg={{ env_path }}
The execution result when using lookup is as follows.
$ ansible-playbook playbook.yml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [target01]
TASK [pipe path]] **************************************************************
ok: [target01] => {
"msg": "/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin"
}
TASK [env path]] ***************************************************************
ok: [target01] => {
"msg": "/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin"
}
PLAY RECAP *********************************************************************
target01 : ok=3 changed=0 unreachable=0 failed=0
Here, I was logged in as ec2-user.
Try setting PATH in environment.
In advance, do sudo su -
and check ʻecho $ PATH`.
$ sudo su -
# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin:/root/bin
The PlayBook looks like this:
playbook.yml
- hosts: all
remote_user: ec2-user
environment:
PATH: "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin:/root/bin"
tasks:
- command: echo $PATH
register: become_path
become: true
changed_when: False
- name: become
debug: var=become_path.stdout
- command: echo $PATH
register: not_become_path
changed_when: False
- name: not become
debug: var=not_become_path.stdout
Let's run it.
$ ansible-playbook playbook.yml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [target01]
TASK [command] *****************************************************************
ok: [target01]
TASK [become] ******************************************************************
ok: [target01] => {
"become_path.stdout": "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin:/root/bin"
}
TASK [command] *****************************************************************
ok: [target01]
TASK [not become] **************************************************************
ok: [target01] => {
"not_become_path.stdout": "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin:/root/bin"
}
PLAY RECAP *********************************************************************
target01 : ok=5 changed=0 unreachable=0 failed=0
Since ʻenvironment:is set for PlayBook, both when
become: true` and not, it is the set PATH.
By the way, ʻenvironment:` can also be written in the task. If you want to set it for each task, you need to specify it for each task. The PlayBook looks like this:
playbook.yml
- hosts: all
remote_user: ec2-user
tasks:
- command: echo $PATH
register: become_path
become: true
changed_when: False
environment:
PATH: "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin:/root/bin"
- name: become
debug: var=become_path.stdout
- command: echo $PATH
register: not_become_path
changed_when: False
environment:
PATH: "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin:/root/bin"
- name: not become
debug: var=not_become_path.stdout
The execution result will be the same as when ʻenvironment:` is set for the entire PlayBook.
The scope of ʻenvironment:` set for PlayBook and Task is the set range. For example, if you set it for a PlayBook, it will not affect another PlayBook. If you enumerate the commands yourself and execute them with / bin / sh, you also have to write a command to restore the set PATH, but Ansible's PlayBook is convenient because it will do that automatically. ..
This time, I introduced how to set PATH using environment.
The PATH setting method is as described, but PATH-dependent PlayBooks can get stuck in unexpected pitfalls. When using the shell and command modules in PlayBook, I think it's safe to make a habit of writing with the full path.
May get stuck in a pitfall (PATH dependent)
- command: cmd
Safe writing
- command: /usr/local/bin/cmd
When using a configuration management tool like Ansible, it's a good idea to try to be able to operate with maintainability and robustness in mind, rather than simply operating.
Recommended Posts