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:
...
リンク
- はじめてAnsibleを使う人が知っておきたい7つのモジュール
- explain about module(Japanese)
- Ansibleでファイルの中身を一括して置換する方法
-
GATHERING FACTS(Ansible Tutorial)
setupモジュールにつて -
Inventory File
グループ化やansible用環境変数など