Ansible

Ansible覚え書き

More than 1 year has passed since last update.

Ansibleに関する自分のための覚え書き。常時更新。内容が増えたらページを分けます。


インストール


CentOS7

### 必要なパッケージのインストール

$ sudo yum install gcc python-devel python-yaml libffi-devel openssl-devel
$ sudo sh -c "curl -kL https://bootstrap.pypa.io/get-pip.py | python"

### 念のためsetuptoolsのアップグレード
$ sudo pip install --upgrade setuptools

### ansibleのインストール
$ sudo pip install ansible

プロキシ設定が必要な場合

### yumのプロキシ設定

$ sudo vi /etc/yum.conf
================================================
...
proxy=http://proxy.example.com:8080
================================================

### 必要なパッケージのインストール
$ sudo yum install python-devel python-yaml libffi-devel openssl-devel

### pipのインストールスクリプト取得
$ curl --proxy http://proxy.example.com:8080 -O https://bootstrap.pypa.io/get-pip.py

### pipのインストール
$ LANG=C sudo sh -c "python get-pip.py --proxy='http://proxy.example.com:8080'"
================================================
Collecting pip
Downloading pip-9.0.1-py2.py3-none-any.whl (1.3MB)
100% |################################| 1.3MB 888kB/s
Collecting setuptools
Downloading setuptools-33.1.1-py2.py3-none-any.whl (472kB)
100% |################################| 481kB 2.0MB/s
Collecting wheel
Downloading wheel-0.29.0-py2.py3-none-any.whl (66kB)
100% |################################| 71kB 6.8MB/s
Installing collected packages: pip, setuptools, wheel
Successfully installed pip-9.0.1 setuptools-33.1.1 wheel-0.29.0
================================================

### 念のためsetuptoolsのアップグレード
$ LANG=C sudo pip --proxy http://proxy.example.com:8080 install --upgrade setuptools
================================================
Requirement already up-to-date: setuptools in /usr/lib/python2.7/site-packages
================================================

### ansibleのインストール
$ LANG=C sudo pip --proxy http://proxy.example.com:8080 install ansible
================================================
Collecting ansible
Downloading ansible-2.2.1.0.tar.gz (2.5MB)
100% |################################| 2.5MB 428kB/s
Collecting paramiko (from ansible)
Downloading paramiko-2.1.1-py2.py3-none-any.whl (172kB)
100% |################################| 174kB 2.1MB/s
...

================================================


モジュール


Files


git


git

### NeoBundleを~/.vim/bundle配下にcloneする。depth=1で最新のcommitだけ取ってくる。

git: dest=~/.vim/bundle/neobundle.vim repo=git://github.com/Shougo/neobundle.vim depth=1


copy


copy

### .vimrcの設定ファイルを作成。ファイルはfilesディレクトリに配置しておく

copy: src=.vimrc dest=~/.vimrc mode=0644 backup=yes


-mで指定して使われやすいモジュール


ping

hostsファイルを作成し、対象のサーバをping確認

$ vi hosts

===================
[ansible_test]
mydev ansible_ssh_host=192.168.33.32
===================
# hostsファイルは単にIPアドレスを羅列するだけでもとりあえず使える

$ ansible -i hosts 192.168.33.32 -u vagrant -m ping -k -c paramiko
===================
SSH password:
mydev | success >> {
"changed": false,
"ping": "pong"
}
===================


setup

サーバの情報を収集して出力する

### 単純にホストを指定するだけなら以下のようにシンプルに書ける

$ vi hosts
================================================
192.168.33.32
================================================

$ ansible -i hosts 192.168.33.32 -u vagrant -m setup -k -c paramiko


オプション

オプション
意味

-i
hostsファイル指定。このファイルにあるホスト以外には実行できない

-u
接続先のユーザ名

-m
モジュール指定。ここではping

-k
パスワードが必要な場合指定

-c paramiko
sshにParamikoを利用する


  • -c paramiko はsshpassをインストールしてくださいというメッセージを回避したい場合つける


サンプル


フルパスからディレクトリまでのパスとファイル名をそれぞれに変数に入れててループする

このファイルはあそこ、あのファイルはここに配置したいなぁという時。

例えば

app/controllers/gwbbs/admin/piece/menus_controller.rb

app/controllers/gwbbs/admin/basic_controller.rb
...

のようなパスから

### ループ1回目

file_name=menus_controller.rb
dir_path=app/controllers/gwbbs/admin/piece

### ループ2回目
file_name=basic_controller.rb
dir_path=app/controllers/gwbbs/admin

のようにディレクトリのパスとファイル名をそれぞれ変数に入れてループしたい時は以下のようにする。

### 1value_to_2variable.yml

================================================
---
- hosts: all
tasks:
- name: フルパスをディレクトリとファイル名に分けて変数に格納する
include: 1value_to_2variable_work.yml
with_items:
- fullpath: app/controllers/gwbbs/admin/piece/menus_controller.rb
- fullpath: app/controllers/gwbbs/admin/basic_controller.rb
loop_control:
loop_var: fullpath_for_work
================================================

### 1value_to_2variable_work.yml
================================================
---
- name: ファイル名を変数file_nameに格納する
shell: basename {{ fullpath_for_work.fullpath }}
register: file_name

- name: ディレクトリのパスを変数dir_pathに格納する
shell: echo {{ fullpath_for_work.fullpath }} | sed -e 's%/{{ file_name.stdout }}%%'
register: dir_path

- debug: var=file_name.stdout
ignore_errors: True

- debug: var=dir_path.stdout
ignore_errors: True
================================================

実行結果

$ ansible-playbook -i "127.0.0.1," -k 1value_to_2variable.yml -c paramiko

================================================
SSH password:

PLAY [all] *********************************************************************

TASK [setup] *******************************************************************
ok: [127.0.0.1]

TASK [フルパスをディレクトリとファイル名に分けて変数に格納する] ********************************************
included: /home/prefuser/pref_tokushima_jp/deploy/jorurigw/1value_to_2variable_work.yml for 127.0.0.1
included: /home/prefuser/pref_tokushima_jp/deploy/jorurigw/1value_to_2variable_work.yml for 127.0.0.1

TASK [ファイル名を変数file_nameに格納する] **************************************************
changed: [127.0.0.1]

TASK [ディレクトリのパスを変数dir_pathに格納する] ***********************************************
changed: [127.0.0.1]

TASK [debug] *******************************************************************
ok: [127.0.0.1] => {
"file_name.stdout": "menus_controller.rb"
}

TASK [debug] *******************************************************************
ok: [127.0.0.1] => {
"dir_path.stdout": "app/controllers/gwbbs/admin/piece"
}

TASK [ファイル名を変数file_nameに格納する] **************************************************
changed: [127.0.0.1]

TASK [ディレクトリのパスを変数dir_pathに格納する] ***********************************************
changed: [127.0.0.1]

TASK [debug] *******************************************************************
ok: [127.0.0.1] => {
"file_name.stdout": "basic_controller.rb"
}

TASK [debug] *******************************************************************
ok: [127.0.0.1] => {
"dir_path.stdout": "app/controllers/gwbbs/admin"
}

PLAY RECAP *********************************************************************
127.0.0.1 : ok=11 changed=4 unreachable=0 failed=0
================================================


test.yml

対象のサーバで echo "hello"を実行する

$ vi hosts

===================
[ansible_test]
mydev02 ansible_ssh_host=192.168.33.32
mydev03 ansible_ssh_host=192.168.33.33
===================

$ vi test.yml
===================
- hosts: all
user: vagrant
gather_facts: no
tasks:
- name: run command and ignore the result
command: /bin/echo "hello"
register: hello

- debug: var=hello.stdout
ignore_errors: True
===================

gather_facts: no 実行前に対象サーバの情報を収集する。

時間がかかるのでテストはnoにしている。

$ ansible-playbook -i hosts test.yml -vvv -k

SSH password:
PLAY [all] ********************************************************************
TASK: [run command and ignore the result] *************************************
<192.168.33.32> ESTABLISH CONNECTION FOR USER: vagrant on PORT 22 TO 192.168.33.32
<192.168.33.33> ESTABLISH CONNECTION FOR USER: vagrant on PORT 22 TO 192.168.33.33
...
TASK: [debug var=hello.stdout] ************************************************
<192.168.33.32> ESTABLISH CONNECTION FOR USER: vagrant on PORT 22 TO 192.168.33.32
<192.168.33.33> ESTABLISH CONNECTION FOR USER: vagrant on PORT 22 TO 192.168.33.33
ok: [mydev02] => {
"hello.stdout": "hello"
}
ok: [mydev03] => {
"hello.stdout": "hello"
}
PLAY RECAP ********************************************************************
mydev02 : ok=2 changed=1 unreachable=0 failed=0
mydev03 : ok=2 changed=1 unreachable=0 failed=0


hand_out_sshkey.yml

対象のサーバにSSH公開鍵を設置する。このままだと既存に設定があっても追記してしまうので

本来は設定があれば追記しないような内容にした方がよい。いずれページを分ける予定。

$ vi hosts

===================
[ansible_test]
mydev02 ansible_ssh_host=192.168.33.32
===================

$ vi hand_out_sshkey.yml
===================
- hosts: all
user: vagrant
gather_facts: no
vars:
user_name: vagrant
user_group: vagrant
src_public_key_file: /home/vagrant/.ssh/id_rsa.pub
dest_home_path: /home/{{user_name}}
tasks:
- copy: src={{src_public_key_file}} dest={{dest_home_path}} owner={{user_name}} group={{user_group}} mode=0600
- command: mkdir {{dest_home_path}}/.ssh creates={{dest_home_path}}/.ssh
- shell: cat {{dest_home_path}}/id_rsa.pub >> {{dest_home_path}}/.ssh/authorized_keys removes={{dest_home_path}}/.ssh
- command: chmod 600 {{dest_home_path}}/.ssh/authorized_keys removes={{dest_home_path}}/.ssh/authorized_keys
- command: rm {{dest_home_path}}/id_rsa.pub removes={{dest_home_path}}/id_rsa.pub
===================

vars: 変数の設定

$ ansible-playbook -i hosts hand_out_sshkey.yml -vvv -k

SSH password:
PLAY [all] ********************************************************************
TASK: [copy src=/home/vagrant/.ssh/id_rsa.pub dest=/home/vagrant owner=vagrant group=vagrant mode=0600] ***
...
PLAY RECAP ********************************************************************
mydev02 : ok=5 changed=5 unreachable=0 failed=0

$ ssh -l vagrant 192.168.33.32
Last login: Tue Jul 8 09:07:13 2014 from 192.168.33.31


リモートホストで実行結果を取得して利用する

MySQL5.7で/var/log/mysqld.logの中にある仮パスワードを取得してrootパスワードを設定する例

---

- hosts: webservers
gather_facts: no
sudo: yes
tasks:
- name: MySQL Communityのrpmのインストール
yum: name=http://dev.mysql.com/get/mysql57-community-release-el6-7.noarch.rpm

- name: 必要なパッケージのインストール
yum: name={{ item }} state=latest
with_items:
- mysql-community-server

- name: mysqlの起動と自動起動設定
service: name=mysqld state=started enabled=yes

- name: 仮パスワードの取得
shell: grep 'password is generated' /var/log/mysqld.log | awk -F'root@localhost:' '{print $2}' | tr -d ' '
register: mysql_tmp_pass

- name: rootユーザのパスワード変更
shell: /usr/bin/mysql -u root -p'{{mysql_tmp_pass.stdout}}' -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'P@ssw0rd'"
ignore_errors: True


オプション


よく使うオプション

オプション
意味

-k
sshパスワードを入力する

-K
sudoパスワードを入力する

-c paramiko
sshにParamikoを利用する

-vvv
vの数が多いほど情報量が多いデバッグ用オプション


  • -c paramiko をつけないとsshpassをインストールしてくださいという警告が出ることが有る


    • sshpassをインストールすれば回避できる

    • そもそも鍵認証で接続するという方法もある。こっちが主流?



  • -vvv は後ほどある実行関連オプションの--checkをつけると標準出力はstdoutに出力されない


実行関連オプション

オプション
意味

--syntax-check
文法チェック

--list-tasks
タスクリストの表示

--check
ドライrun

--step
step実行

(何もなし)
実行


Symlinkが存在するかどうかの確認

- name: /home/vagrant/hogeがsymlinkであることの確認

stat: path=/home/vagrant/hoge
register: st

- fail:
msg: "/home/vagrant/hogeがありません"
when: st.stat.islnk is not defined

- fail:
msg: "/home/vagrant/hogeはsymlinkではありません"
when: st.stat.islnk == False


PATHを追加する

envの処理でPATHが通らなくてエラーになる場合

shell: /usr/local/rvm/rubies/ruby-2.3.4/bin/gem install bundler

================================================
...
"msg": "/usr/bin/env: ruby: No such file or directory",
"rc": 127,
"stderr": "/usr/bin/env: ruby: No such file or directory\n",
"stderr_lines": [
"/usr/bin/env: ruby: No such file or directory"
...
================================================

### 以下でPATHを設定して実行できる
shell: PATH=/usr/local/rvm/rubies/ruby-2.3.4/bin:${PATH} && gem install bundler
================================================
"stderr": "",
"stderr_lines": [],
"stdout": "Successfully installed bundler-1.15.3\nParsing documentation for bundler-1.15.3\nInstalling ri documentation for bundler-1.15.3\nDone installing documentation for bundler after 4 seconds\n1 gem installed",
================================================

environmentで設定すれば一つ一つ設定する必要がなくなる

---

- hosts: containers
connection: docker
gather_facts: no
become: yes
vars:
rvm_ruby_version: 2.3.4
environment:
PATH: /usr/local/rvm/rubies/ruby-{{ rvm_ruby_version }}/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
roles:
...


リンク