Ansible入門
Ansible
Ansibleサーバのhostを立てて、 AnsibleでWEBとDBサーバを構築していく。 Ansibleでは管理される側にはPythonが入っていて、 あとはSSH接続ができればよい。
- やっていくこと
Ansibleのインストール SSH接続確認 Inventoryファイル編集 # どのサーバを管理するのか記述する ansible.cfg編集 # Ansibleの設定ファイル Playbook編集 # 管理するサーバの構成を記述
- 構成
HOSTサーバ:Ansible WEBサーバ:Use,Apache,PHP DBサーバ:Use,MySQL
Vagrantfileは以下の設定を追記します。
# 変更箇所 # config.vm.box = "bento/centos-6.7" # 追加箇所 config.vm.define "host" do |node| node.vm.box = "bento/centos-6.7" node.vm.hostname = "host" node.vm.network :private_network, ip: "192.168.43.51" end config.vm.define "web" do |node| node.vm.box = "bento/centos-6.7" node.vm.hostname = "web" node.vm.network :private_network, ip: "192.168.43.52" end config.vm.define "db" do |node| node.vm.box = "bento/centos-6.7" node.vm.hostname = "db" node.vm.network :private_network, ip: "192.168.43.53" end
サーバを立ち上げ、立ち上がっているのを確認
$ vagrant up $ vagrant status Current machine states: host running (virtualbox) web running (virtualbox) db running (virtualbox)
Ansibleサーバのhostへssh接続をします。
$ vagrant ssh host
yumでAnsibleインストールできなかった。
$ sudo yum install ansible (略) パッケージ ansible は利用できません。 エラー: 何もしません
epelリポジトリをインストールします
$ sudo yum install epel-release
これはrpmでインストールしてもよい。 https://dl.fedoraproject.org/pub/epel/ 最新はhttps://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpmですね。(2016/08現在)
wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm sudo rpm -Uvh epel-release-latest-7.noarch.rpm
これでもう一度yumでAnsibleをインストールすればできるはず
$ sudo yum install ansible
Ansibleインストール完了
$ ansible --version ansible 2.1.1.0 config file = /etc/ansible/ansible.cfg configured module search path = Default w/o overrides
SSH接続を鍵認証で行えるようにします。
.ssh/config
を作成します。
またパーミッションも変更します。
$ vi .ssh/config Host web HostName 192.168.43.52 User vagrant Host db HostName 192.168.43.53 User vagrant $ ll .ssh/config -rw-rw-r--. 1 vagrant vagrant 67 8月 29 10:34 2016 .ssh/config $ chmod 600 .ssh/config ll .ssh/config -rw-------. 1 vagrant vagrant 67 8月 29 10:34 2016 .ssh/config
次に秘密鍵と公開鍵を作成しwebとdbに公開鍵をコピーします。 コピーしたらhostnameを指定してSSH接続できることを確認
$ ssh-keygen -t rsa $ ssh-keygen -t rsa $ ssh-copy-id web $ ssh web $ ssh-copy-id db $ ssh db
hostsというinventoryファイルを作成し host側でAnsibleコマンドを実行します。 hostsにはwebとdbの情報を記載します。 ここで[グループ名]でグループをつくることができます。 Ansibleコマンドを実行するときallやhostname指定またはグループ指定ができるようになります。
$ vi hosts [web] 192.168.43.52 [db] 192.168.43.53
ansible 対象サーバ -i inventoryファイル(フルパス) -m module名
ex.ping module
$ ansible all -i hosts -m ping 192.168.43.53 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.43.52 | SUCCESS => { "changed": false, "ping": "pong" }
またansible.cfg
にinventoryファイルを指定すれば省略可能です。
-i を抜かしてコマンドが実行できます。
$ ansible all -m ping
$ ansible all -m ping 192.168.43.52 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.43.53 | SUCCESS => { "changed": false, "ping": "pong" }
playbookにサーバにしたい処理を書きます
今回はhogeユーザを追加してみます。
YAMLファイルで記述します。
一行目の「---」YAMLファイルであることを指す
「- hosts」に対象サーバを指定する。今回は「all」で全台へ
管理者権限が必要なので「sudo: yes」とする。
タスクを実行するために「tasks:」モジュールを指定し、
タスクに名前をつけておきます。
- name: add a new user
とし、
userモジュールとnameオプションでhogeユーザを追加します。
$ vi playbook.yml $ cat playbook.yml --- - hosts: all sudo: yes tasks: - name: add a new user user: name=hoge $ ansible-playbook playbook.yml [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.43.52] ok: [192.168.43.53] TASK [add a new user] ********************************************************** changed: [192.168.43.52] changed: [192.168.43.53] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=2 changed=1 unreachable=0 failed=0 192.168.43.53 : ok=2 changed=1 unreachable=0 failed=0
モジュールは冪等なのですでにhogeユーザがいたら、何もしません。
2回目を実行してもOKで返ってきますが、changed=0
となっていることがわかります。
シェルとかだと既にユーザがいたらおかしな挙動をするかもしれませんね。
ここがAnsibleの利点で安全にplaybookを何度も実行できます。
実際にhogeユーザが追加されていることも確認できました。
$ ansible-playbook playbook.yml [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.43.52] ok: [192.168.43.53] TASK [add a new user] ********************************************************** ok: [192.168.43.52] ok: [192.168.43.53] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=2 changed=0 unreachable=0 failed=0 192.168.43.53 : ok=2 changed=0 unreachable=0 failed=0 $ ssh web Last login: Wed Aug 31 22:12:23 2016 from 192.168.43.51 cat /etc/passwd |grep hoge hoge:x:501:501::/home/hoge:/bin/bash
stateオプションを使ってみる。 stateそれが存在するかどうかを指定できる。 hogeユーザが存在しないとする。
user: name=hoge state=absent
実行してみるとユーザが消えていることが確認できる。
[vagrant@host ~]$ ansible-playbook playbook.yml [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.43.52] ok: [192.168.43.53] TASK [add a new user] ********************************************************** changed: [192.168.43.52] changed: [192.168.43.53] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=2 changed=1 unreachable=0 failed=0 192.168.43.53 : ok=2 changed=1 unreachable=0 failed=0 [vagrant@host ~]$ ssh web ^[[ALast login: Wed Aug 31 22:37:46 2016 from 192.168.43.51 [vagrant@web ~]$ cat /etc/passwd |grep hoge [vagrant@web ~]$ logout
ansible-playbookのオプションを確認
--syntax-check
はPlaybookの文法チェック
$ ansible-playbook playbook.yml --syntax-check [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. playbook: playbook.yml
--list-task
はタスク一覧を表示
$ ansible-playbook playbook.yml --list-task [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. playbook: playbook.yml play #1 (all): all TAGS: [] tasks: add a new user TAGS: []
--check
はドライランを実行
$ ansible-playbook playbook.yml --check
Playbookでは変数も使えます。Playbookを使い回すときに便利になる。
今回はユーザ名を変数で扱ってみます。
[tasks:]の前に[vats:]というのをつけて
キーと値を管理します。
ここではusername: hoge
変数とするときは{{キー}}
とすればよい
$ cat playbook.yml --- - hosts: all sudo: yes vars: username: hoge tasks: - name: add a new user user: name={{username}} ]$ ansible-playbook playbook.yml [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.43.52] ok: [192.168.43.53] TASK [add a new user] ********************************************************** changed: [192.168.43.52] changed: [192.168.43.53] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=2 changed=1 unreachable=0 failed=0 192.168.43.53 : ok=2 changed=1 unreachable=0 failed=0
実行時にユーザに変数の値を入力させることもできます。 「vars: prompt」として「username: "Enter username"」とする。 これで実行時にユーザ名が聞かれます。
$ cat playbook.yml --- - hosts: all sudo: yes # vars: # username: hoge vars_prompt: username: "Enter username" tasks: - name: add a new user user: name={{username}} $ ansible-playbook playbook.yml [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. [DEPRECATION WARNING]: Using the 'short form' for vars_prompt has been deprecated. This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. Enter username: hoge PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.43.53] ok: [192.168.43.52] TASK [add a new user] ********************************************************** ok: [192.168.43.52] ok: [192.168.43.53] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=2 changed=0 unreachable=0 failed=0 192.168.43.53 : ok=2 changed=0 unreachable=0 failed=0
WEBにApacheをインストールするplaybookを書きます。
yumモジュールを使い、state=latest
とすると最新版をインストールします。
serviceモジュールを使い、再起動時に自動起動するように設定します。
--- - hosts: all sudo: yes tasks: - name: add a new user user: name=hoge - hosts: web sudo: yes tasks: - name: install apache yum: name=httpd state=latest - name: start apache and enabled service: name=httpd state=started enabled=yes ~
WEBブラウザのURLに192.168.43.52
でアクセスするとApacheの画面が出てきます。
次はApacheのドキュメントルートの所有者を変更し、 ファイルを置いてWEBブラウザ上から確認してみます。 最初に適当にindex.htmlを作成してかた、 playbookに書いていきます。
まずは、ドキュメントルートの所有者変更は
ファイルやディレクトリに関するfileモジュールを使います。
対象ディレクトリとownerを指定し、recurse=yes
にすることで
再帰的に反映されます。
次に、index.htmlファイルを転送するために copyモジュールを使い、 対象ファイルと、対象ディレクトリ、所有者を指定します。
--- - hosts: all sudo: yes tasks: - name: add a new user user: name=hoge - hosts: web sudo: yes tasks: - name: install apache yum: name=httpd state=latest - name: start apache and enabled service: name=httpd state=started enabled=yes - name: change owner file: dest=/var/www/html owner=vagrant recurse=yes - name: copy index.html copy: src=./index.html dest=/var/www/html/index.html owner=vagrant
ansible-playbookを実行するとエラーが出ました。
TASK [copy index.html] ********************************************************* fatal: [192.168.43.52]: FAILED! => {"changed": false, "checksum": "82a4c7e6c69f12b6fdc25ec54a16ef7a1bfbecaf", "failed": true, "msg": "Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"}
libselinux-python
がインストールされていないとエラーが出たので、
WEBとDBに対してインストールするようにplaybook追記します。
--- - hosts: all sudo: yes tasks: - name: add a new user user: name=hoge - name: install libselinux-python yum: name=libselinux-python state=latest
これで成功。 WEBブラウザで確認し反映されていることを確認。
PHPパッケージインストール
複数のパッケージをインストールする際、
yumモジュールをを何度も書くことよりも、
インストールしたいパッケージをリスト化したほうがよいです。
nameのあとに{{item}}
として、
with_items
を使い、リスト化します。
これでリスト化したパッケージが一つずつ{{item}}
に代入され
yumが実行されインストールされます。
Apache再起動もplaybook上で行います。 serviceモジュールで再起動しますが、 notifyとhandlersモジュールを使い、 タスクで変更があった場合、再起動するようにします。 handlersは最後に一回だけ呼ばれるもので、 複数の箇所からnotifyで呼ばれても実行するのは最後の一回です。 また、PHPファイルを作成し、WEBに転送して、WEBブラウザ上で表示されるか確認し、 Apache再起動されているか確認します。
- name: install php packages yum: name={{item}} state=latest with_items: - php - php-devel - php-mbstring - php-mysql notify: - restart apache - name: copy hello.php copy: src=./hello.php dest=/var/www/html/hello.php owner=vagrant handlers: - name: restart apache service: name=httpd state=restarted
PHPのパッケージインストールと ファイルの転送、Apache再起動が実施されています。
TASK [install php packages] **************************************************** changed: [192.168.43.52] => (item=[u'php', u'php-devel', u'php-mbstring', u'php-mysql']) TASK [copy hello.php] ********************************************************** changed: [192.168.43.52] RUNNING HANDLER [restart apache] *********************************************** changed: [192.168.43.52] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=11 changed=3 unreachable=0 failed=0 192.168.43.53 : ok=3 changed=0 unreachable=0 failed=0
もう一度ansible-playbookを実行してみると 既にPHPパッケージがインストールされているので、 notifyからhandlersが呼ばれていないので、 Apache再起動されていないのが確認できます。
TASK [install php packages] **************************************************** ok: [192.168.43.52] => (item=[u'php', u'php-devel', u'php-mbstring', u'php-mysql']) TASK [copy hello.php] ********************************************************** ok: [192.168.43.52] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=10 changed=0 unreachable=0 failed=0 192.168.43.53 : ok=3 changed=0 unreachable=0 failed=0
DBへMySQLをインストールします。
- hosts: db sudo: yes tasks: - name: install mysql yum: name=mysql-server state=latest - name: start mysql and enabled service: name=mysqld state=started enabled=yes
DBでMySQLがインストールされていることを確認
$ ssh db Last login: Thu Sep 1 10:11:31 2016 from 192.168.43.51 mysql --version mysql Ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64) using readline 5.1
MySQLデータベースを作成し、ユーザを設定します。
mysql_db
モジュールを使用します。
ユーザはmysql_user
を使用します。
priv
でデータベースの全てのテーブルに対し、権限を付与します。
- name: create a database mysql_db: name=mydb state=present - name: create a name for mydb mysql_user: name=dbuser password=******** priv=mydb.*:ALL state=present
データベースを作るときにpython mysqldb
が必要らしいのでインストールする。
TASK [create a database] ******************************************************* fatal: [192.168.43.53]: FAILED! => {"changed": false, "failed": true, "msg": "the python mysqldb module is required"}
変数を使ってまとめてインストールします。
tasks: - name: install mysql yum: name={{item}} state=latest with_items: - mysql-server - MySQL-python
DBにSSH接続してデータベースが作成されていることを確認
$ ssh db Last login: Thu Sep 1 10:19:04 2016 from 192.168.43.51 $ mysql -u dbuser -p mydb Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 Server version: 5.1.73 Source distribution Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mydb | | test | +--------------------+ 3 rows in set (0.00 sec) mysql> exit Bye