Ansible 시작 - xmlangel/ansible GitHub Wiki

Ansible은 chef, puppet 과 같이 프로비저닝을할 수 있게 해주는 툴이다.

관리하고자 하는 대상에 agent 없이 ssh 접속을 통해서 관리를 할 수 있다.

단순한 방법으로 SSH를 원격 접속하지 않고, 전송은 Pluggable Transport를 지원하며 chroot, lxc, jail 컨테이너를 사용하여 관리되는 요소들을 로컬에서 관리한다고 한다.

python 을 기본으로 이용한다. 그래서 기본적으로 파이선이 깔려 있어야지만 동작을 한다.

실행은 패러럴하게 실행이 된다.

호스트리스트(inventory)를 작성하고 호스트 리스트를 기준으로 접속해서 작업이 이루어지는 형태임.

SSH키를 사용하는 것이 권장되지만 –ask-pass 옵션을 사용하여 패스워드 인증을 사용하는 것도 가능하다. 만약 sudo 기능을 사용하고 이때에 비밀번호를 입력할 필요가 있다면 –ask-become-pass 옵션을 이용하여 이용 가능

Inventory

기본적으로 /etc/ansible/hosts 에 인벤터리를 생성하지만 -i 옵션으로 지정해서 사용하는것이 편하다.

호스트 아이피만 지정하는 거

   192.168.122.221
   192.168.122.222
   192.168.122.223

전체에대해서 비밀번호를 지정 가능

[all:vars]
ansible_connection=ssh
#ansible_ssh_user=root
#ansible_ssh_pass=비밀번호

key 기반이용

[master]
10.122.38.189 ansible_ssh_private_key_file=/home/test.pem ansible_ssh_user=ubuntu

비밀번호 이용

[slave]
10.122.37.211 ansible_ssh_user=root ansible_ssh_pass=비밀번호
[vagrant]
#10.0.2.15

이제 모든 노드에 핑을 때리려면 아래와 같이 하면된다.

ansible all -m ping

인벤토리 지정 master 에 대해서만 ping

ansible -i host master -m ping

http://docs.ansible.com/ansible/latest/intro_inventory.html

List of Behavioral Inventory Parameters
As alluded to above, setting the following variables controls how ansible interacts with remote hosts.

Host connection:

ansible_connection
Connection type to the host. This can be the name of any of ansible’s connection plugins. SSH protocol types are smart, ssh or paramiko. The default is smart. Non-SSH based types are described in the next section.
Note
Ansible 2.0 has deprecated the “ssh” from ansible_ssh_user, ansible_ssh_host, and ansible_ssh_port to become ansible_user, ansible_host, and ansible_port. If you are using a version of Ansible prior to 2.0, you should continue using the older style variables (ansible_ssh_*). These shorter variables are ignored, without warning, in older versions of Ansible.
General for all connections:

ansible_host
The name of the host to connect to, if different from the alias you wish to give to it.
ansible_port
The ssh port number, if not 22
ansible_user
The default ssh user name to use.
Specific to the SSH connection:

ansible_ssh_pass
The ssh password to use (never store this variable in plain text; always use a vault. See Variables and Vaults)
ansible_ssh_private_key_file
Private key file used by ssh. Useful if using multiple keys and you don’t want to use SSH agent.
ansible_ssh_common_args
This setting is always appended to the default command line for sftp, scp, and ssh. Useful to configure a ProxyCommand for a certain host (or group).
ansible_sftp_extra_args
This setting is always appended to the default sftp command line.
ansible_scp_extra_args
This setting is always appended to the default scp command line.
ansible_ssh_extra_args
This setting is always appended to the default ssh command line.
ansible_ssh_pipelining
Determines whether or not to use SSH pipelining. This can override the pipelining setting in ansible.cfg.
ansible_ssh_executable (added in version 2.2)
This setting overrides the default behavior to use the system ssh. This can override the ssh_executable setting in ansible.cfg.
Privilege escalation (see Ansible Privilege Escalation for further details):

ansible_become
Equivalent to ansible_sudo or ansible_su, allows to force privilege escalation
ansible_become_method
Allows to set privilege escalation method
ansible_become_user
Equivalent to ansible_sudo_user or ansible_su_user, allows to set the user you become through privilege escalation
ansible_become_pass
Equivalent to ansible_sudo_pass or ansible_su_pass, allows you to set the privilege escalation password (never store this variable in plain text; always use a vault. See Variables and Vaults)
ansible_become_exe
Equivalent to ansible_sudo_exe or ansible_su_exe, allows you to set the executable for the escalation method selected
ansible_become_flags
Equivalent to ansible_sudo_flags or ansible_su_flags, allows you to set the flags passed to the selected escalation method. This can be also set globally in ansible.cfg in the sudo_flags option
Remote host environment parameters:

ansible_shell_type
The shell type of the target system. You should not use this setting unless you have set the ansible_shell_executable to a non-Bourne (sh) compatible shell. By default commands are formatted using sh-style syntax. Setting this to csh or fish will cause commands executed on target systems to follow those shell’s syntax instead.
ansible_python_interpreter
The target host python path. This is useful for systems with more than one Python or not located at /usr/bin/python such as *BSD, or where /usr/bin/python is not a 2.X series Python. We do not use the /usr/bin/env mechanism as that requires the remote user’s path to be set right and also assumes the python executable is named python, where the executable might be named something like python2.6.
ansible_*_interpreter
Works for anything such as ruby or perl and works just like ansible_python_interpreter. This replaces shebang of modules which will run on that host.
New in version 2.1.

ansible_shell_executable
This sets the shell the ansible controller will use on the target machine, overrides executable in ansible.cfg which defaults to /bin/sh. You should really only change it if is not possible to use /bin/sh (i.e. /bin/sh is not installed on the target machine or cannot be run from sudo.).
Examples from an Ansible-INI host file:

some_host         ansible_port=2222     ansible_user=manager
aws_host          ansible_ssh_private_key_file=/home/example/.ssh/aws.pem
freebsd_host      ansible_python_interpreter=/usr/local/bin/python
ruby_module_host  ansible_ruby_interpreter=/usr/bin/ruby.1.9.3
Non-SSH connection types
As stated in the previous section, Ansible executes playbooks over SSH but it is not limited to this connection type. With the host specific parameter ansible_connection=<connector>, the connection type can be changed. The following non-SSH based connectors are available:

local

This connector can be used to deploy the playbook to the control machine itself.

docker

This connector deploys the playbook directly into Docker containers using the local Docker client. The following parameters are processed by this connector:

ansible_host
The name of the Docker container to connect to.
ansible_user
The user name to operate within the container. The user must exist inside the container.
ansible_become
If set to true the become_user will be used to operate within the container.
ansible_docker_extra_args
Could be a string with any additional arguments understood by Docker, which are not command specific. This parameter is mainly used to configure a remote Docker daemon to use.
Here is an example of how to instantly deploy to created containers:

- name: create jenkins container
  docker_container:
    docker_host: myserver.net:4243
    name: my_jenkins
    image: jenkins

- name: add container to inventory
  add_host:
    name: my_jenkins
    ansible_connection: docker
    ansible_docker_extra_args: "--tlsverify --tlscacert=/path/to/ca.pem --tlscert=/path/to/client-cert.pem --tlskey=/path/to/client-key.pem -H=tcp://myserver.net:4243"
    ansible_user: jenkins
  changed_when: false

- name: create directory for ssh keys
  delegate_to: my_jenkins
  file:
    path: "/var/jenkins_home/.ssh/jupiter"
    state: directory

Parallelism and Shell Commands

가이드에서는 비밀번호를 입력하는 거 보다 ssh-agent를 이용해서 key 기반인증을 하는게 낳다고 한다. -a 옵션을 이용하거나 -m 을 이용해서 shell command를 직접 입력할 수 있다.

ansible -i hosts all -a "/bin/bash /root/ansible_test/test.sh"

ansible -i hosts all -m shell -a  "/root/ansible_test/test.sh"

result
10.122.37.211 | SUCCESS | rc=0 >>
this is test

http://docs.ansible.com/ansible/latest/intro_adhoc.html#parallelism-and-shell-commands

Let’s use Ansible’s command line tool to reboot all web servers in Atlanta, 10 at a time. First, let’s set up SSH-agent so it can remember our credentials:

$ ssh-agent bash
$ ssh-add ~/.ssh/id_rsa
If you don’t want to use ssh-agent and want to instead SSH with a password instead of keys, you can with --ask-pass (-k), but it’s much better to just use ssh-agent.

Now to run the command on all servers in a group, in this case, atlanta, in 10 parallel forks:

$ ansible atlanta -a "/sbin/reboot" -f 10

/usr/bin/ansible will default to running from your user account. If you do not like this behavior, pass in “-u username”. If you want to run commands as a different user, it looks like this:

$ ansible atlanta -a "/usr/bin/foo" -u username

Often you’ll not want to just do things from your user account. If you want to run commands through privilege escalation:

$ ansible atlanta -a "/usr/bin/foo" -u username --become [--ask-become-pass]

Use --ask-become-pass (-K) if you are not using a passwordless privilege escalation method (sudo/su/pfexec/doas/etc). This will interactively prompt you for the password to use. Use of a passwordless setup makes things easier to automate, but it’s not required.

It is also possible to become a user other than root using --become-user:

$ ansible atlanta -a "/usr/bin/foo" -u username --become-user otheruser [--ask-become-pass]

The -f 10 in the above specifies the usage of 10 simultaneous processes to use. You can also set this in Configuration file to avoid setting it again. The default is actually 5, which is really small and conservative. You are probably going to want to talk to a lot more simultaneous hosts so feel free to crank this up. If you have more hosts than the value set for the fork count, Ansible will talk to them, but it will take a little longer. Feel free to push this value as high as your system can handle!

You can also select what Ansible “module” you want to run. Normally commands also take a -m for module name, but the default module name is ‘command’, so we didn’t need to specify that all of the time. We’ll use -m in later examples to run some other About Modules.

Note The command - Executes a command on a remote node module does not support extended shell syntax like piping and redirects (although shell variables will always work). If your command requires shell-specific syntax, use the shell module instead. Read more about the differences on the About Modules page. Using the shell - Execute commands in nodes. module looks like this:

$ ansible raleigh -m shell -a 'echo $TERM'

When running any command with the Ansible ad hoc CLI (as opposed to Playbooks), pay particular attention to shell quoting rules, so the local shell doesn’t eat a variable before it gets passed to Ansible. For example, using double rather than single quotes in the above example would evaluate the variable on the box you were on.

So far we’ve been demoing simple command execution, but most Ansible modules are not simple imperative scripts. Instead, they use a declarative model, calculating and executing the actions required to reach a specified final state. Furthermore, they achieve a form of idempotence by checking the current state before they begin, and if the current state matches the specified final state, doing nothing. However, we also recognize that running arbitrary commands can be valuable, so Ansible easily supports both.

File Transfer

Ansible 은 SCP를 이용해서 많은 파일을 패러럴하게 복사할수 있다.

ansible -i hosts all -m copy -a  "src=test.txt  dest=/root/ansible_test/test.txt"
result
10.122.37.211 | SUCCESS => {
    "changed": true,
    "checksum": "e10b20a1a89efae352e2a60ae5b904792190f9ce",
    "dest": "/root/ansible_test/test.txt",
    "failed": false,
    "gid": 0,
    "group": "root",
    "md5sum": "cc95ede37809d2f1803980dd42506a31",
    "mode": "0644",
    "owner": "root",
    "size": 73,
    "src": "/root/.ansible/tmp/ansible-tmp-1508860461.32-204845801831980/source",
    "state": "file",
    "uid": 0

.
├── test.sh
└── test.txt

http://docs.ansible.com/ansible/latest/intro_adhoc.html#file-transfer

Here’s another use case for the /usr/bin/ansible command line. Ansible can SCP lots of files to multiple machines in parallel.


To transfer a file directly to many servers:

$ ansible atlanta -m copy -a "src=/etc/hosts dest=/tmp/hosts"
If you use playbooks, you can also take advantage of the template module, which takes this another step further. (See module and playbook documentation).

The file module allows changing ownership and permissions on files. These same options can be passed directly to the copy module as well:

$ ansible webservers -m file -a "dest=/srv/foo/a.txt mode=600"
$ ansible webservers -m file -a "dest=/srv/foo/b.txt mode=600 owner=mdehaan group=mdehaan"
The file module can also create directories, similar to mkdir -p:

$ ansible webservers -m file -a "dest=/path/to/c mode=755 owner=mdehaan group=mdehaan state=directory"
As well as delete directories (recursively) and delete files:

$ ansible webservers -m file -a "dest=/path/to/c state=absent"

Managing Packages

패키지 설치 ubuntu 는 apt, redhat 계열은 yum 으로 설치 가능

이미 설치된경우 아래와 같이 changed false

ansible -i hosts all  -m apt -a "name=htop state=present"
10.122.37.211 | SUCCESS => {
    "cache_update_time": 1507836265,
    "cache_updated": false,
    "changed": false,
    "failed": false
}

설치안되어있으면 설치한다.

ansible -i hosts all  -m apt -a "name=htop state=present"

10.122.37.211 | SUCCESS => {
    "cache_update_time": 1507836265,
    "cache_updated": false,
    "changed": true,
    "failed": false,
    "stderr": "",
    "stderr_lines": [],
    "stdout": "Reading package lists...\nBuilding dependency tree...\nReading state information...\nThe following NEW packages will be installed:\n  htop\n0 upgraded, 1 newly installed, 0 to remove and 98 not upgraded.\nNeed to get 0 B/76.4 kB of archives.\nAfter this operation, 215 kB of additional disk space will be used.\nSelecting previously unselected package htop.\r\n(Reading database ... \r(Reading database ... 5%\r(Reading database ... 10%\r(Reading database ... 15%\r(Reading database ... 20%\r(Reading database ... 25%\r(Reading database ... 30%\r(Reading database ... 35%\r(Reading database ... 40%\r(Reading database ... 45%\r(Reading database ... 50%\r(Reading database ... 55%\r(Reading database ... 60%\r(Reading database ... 65%\r(Reading database ... 70%\r(Reading database ... 75%\r(Reading database ... 80%\r(Reading database ... 85%\r(Reading database ... 90%\r(Reading database ... 95%\r(Reading database ... 100%\r(Reading database ... 79880 files and directories currently installed.)\r\nPreparing to unpack .../htop_2.0.1-1ubuntu1_amd64.deb ...\r\nUnpacking htop (2.0.1-1ubuntu1) ...\r\nProcessing triggers for mime-support (3.59ubuntu1) ...\r\nProcessing triggers for man-db (2.7.5-1) ...\r\nSetting up htop (2.0.1-1ubuntu1) ...\r\n",
    "stdout_lines": [
        "Reading package lists...",
        "Building dependency tree...",
        "Reading state information...",
        "The following NEW packages will be installed:",
        "  htop",
        "0 upgraded, 1 newly installed, 0 to remove and 98 not upgraded.",
        "Need to get 0 B/76.4 kB of archives.",
        "After this operation, 215 kB of additional disk space will be used.",
        "Selecting previously unselected package htop.",
        "(Reading database ... ",
        "(Reading database ... 5%",
        "(Reading database ... 10%",
        "(Reading database ... 15%",
        "(Reading database ... 20%",
        "(Reading database ... 25%",
        "(Reading database ... 30%",
        "(Reading database ... 35%",
        "(Reading database ... 40%",
        "(Reading database ... 45%",
        "(Reading database ... 50%",
        "(Reading database ... 55%",
        "(Reading database ... 60%",
        "(Reading database ... 65%",
        "(Reading database ... 70%",
        "(Reading database ... 75%",
        "(Reading database ... 80%",
        "(Reading database ... 85%",
        "(Reading database ... 90%",
        "(Reading database ... 95%",
        "(Reading database ... 100%",
        "(Reading database ... 79880 files and directories currently installed.)",
        "Preparing to unpack .../htop_2.0.1-1ubuntu1_amd64.deb ...",
        "Unpacking htop (2.0.1-1ubuntu1) ...",
        "Processing triggers for mime-support (3.59ubuntu1) ...",
        "Processing triggers for man-db (2.7.5-1) ...",
        "Setting up htop (2.0.1-1ubuntu1) ..."
    ]
}

There are modules available for yum and apt. Here are some examples with yum.

Ensure a package is installed, but don’t update it:

$ ansible webservers -m yum -a "name=acme state=present"
Ensure a package is installed to a specific version:

$ ansible webservers -m yum -a "name=acme-1.5 state=present"
Ensure a package is at the latest version:

$ ansible webservers -m yum -a "name=acme state=latest"
Ensure a package is not installed:

$ ansible webservers -m yum -a "name=acme state=absent"
Ansible has modules for managing packages under many platforms. If there isn’t a module for your package manager, you can install packages using the command module or (better!) contribute a module for your package manager. Stop by the mailing list for info/details.

Managing Services

서비스를 시작중지할 수 있다.

ansible -i hosts all  -m service -a "name=httpd state=starte"

Ensure a service is started on all webservers:

$ ansible webservers -m service -a "name=httpd state=started" Alternatively, restart a service on all webservers:

$ ansible webservers -m service -a "name=httpd state=restarted" Ensure a service is stopped:

$ ansible webservers -m service -a "name=httpd state=stopped"

⚠️ **GitHub.com Fallback** ⚠️