#contents ** Ansibleとはなにか? [#lf812133] - 概要:サーバーの構成管理ツール - 公式サイト: -- 公式サイト: www.ansible.com -- ドキュメンテーション: docs.ansible.com - 知識: -- Unixコマンド -- Vim -- Vagrant -- YAML - 環境: -- MacOS X -- Vagrant ** サーバー構成 [#xfe74c1f] - Host -- Ansible -- Python実行環境 -- Inventory:どのサーバーを管理するか記述 -- ansible.cfg:Ansible全体の設定を記述 -- Playbook:管理対象に対して具体的にどのような設定(構成)を行うか記述 - Web -- 管理対象 -- Python実行環境 -- Hostとの鍵認証/SSH接続 -- User / Apache / PHP ※Ansibleで構成管理 - DB -- 管理対象 -- Python実行環境 -- Hostとの鍵認証/SSH接続 -- User / MySQL ※Ansibleで構成管理 ** Vagrantでサーバーを起動 [#lc2bfb4d] - 利用可能なBoxファイルを検索 -- [[Atlas:https://atlas.hashicorp.com/boxes/search?utm_source=vagrantcloud.com&vagrantcloud=1]] >> Discover Vagrant Boxes - 'bento/centos-6.7'のVagrant boxを利用 - Vagrantfileを生成 $ cd ~/Documents/MyVagrant $ mkdir ansible_lessons $ cd ansible_lessons $ vagrant init bento/centos-6.7 - Vagrantfileを開き下記をコメントアウト $ vi 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 ... ... ==> host: Successfully added box 'bento/centos-6.7' (v2.2.7) for 'virtualbox'! ... ... $ vagrant status Current machine states: host running (virtualbox) web running (virtualbox) db running (virtualbox) This environment represents multiple VMs. The VMs are all listed above with their current state. For more information about a specific VM, run `vagrant status NAME`. ** Ansibleをインストールしてみよう [#ja6cc9b9] - Ansibleをインストールするhostにssh接続 $ vagrant ssh host - epelリポジトリをダウンロード -- [[Index of /pub/epel/6/x86_64:https://dl.fedoraproject.org/pub/epel/6/x86_64/]]より[[epel-release-6-8.noarch.rpmのリンクアドレス:https://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm]]をコピー [vagrant@host ~]$ wget https://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm - epelリポジトリをインストール [vagrant@host ~]$ sudo rpm -Uvh epel-release-6-8.noarch.rpm - Ansibleをインストール [vagrant@host ~]$ sudo yum -y install ansible [vagrant@host ~]$ $ ansible --version ansible 2.1.1.0 config file = /etc/ansible/ansible.cfg configured module search path = Default w/o overrides ** SSH接続の設定をしていこう [#w1b86105] - WebとDBに対してssh configを設定 [vagrant@host ~]$ vi .ssh/config Host web HostName 192.168.43.52 Host db HostName 192.168.43.53 $ chmod 600 .ssh/config - 秘密鍵/公開鍵作成 $ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/vagrant/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: - WebとDBに公開鍵を転送 &color(red){*};Vagrantユーザーのデフォルトパスワードは 'vagrant' $ ssh-copy-id web The authenticity of host '192.168.43.52 (192.168.43.52)' can't be established. RSA key fingerprint is 90:d8:41:6f:c5:39:1d:54:0d:43:4e:34:dc:f1:d2:6b. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.43.52' (RSA) to the list of known hosts. vagrant@192.168.43.52's password: $ ssh-copy-id db - SSH接続確認 $ ssh web $ exit $ ssh db $ exit ** ansibleを使ってみよう [#s1785f10] - Inventoryファイル作成 [vagrant@host ~]$ vi hosts [web] 192.168.43.52 [db] 192.168.43.53 - ansible実行(WebとDBに対してping確認) $ 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 config作成(ansible実行時にInventoryファイルの指定を省略可能に) $ vi ansible.cfg [defaults] hostfile = ./hosts $ ansible all -m ping 192.168.43.52 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.43.53 | SUCCESS => { "changed": false, "ping": "pong" } ** playbookを使ってみよう [#c059e591] - Playbook作成 $ vi playbook.yml --- - hosts: all sudo: yes tasks: - name: add a new user user: name=yuji - Playbook実行 $ 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.53] changed: [192.168.43.52] 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 - Playbook再実行 &color(red){*};冪等性が担保されていることの確認 $ 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.53] ok: [192.168.43.52] 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 - yuji ユーザーが作成されていることの確認 $ ssh web $ cat /etc/passwd yuji:x:501:501::/home/yuji:/bin/bash $ exit $ ssh db $ cat /etc/passwd yuji:x:501:501::/home/yuji:/bin/bash $ exit ** 公式ドキュメントを見てみよう [#n740d97b] - docs.ansible.com >> Module Index にてモジュール一覧と使用方法(オプション等)の情報あり - [[userモジュール:http://docs.ansible.com/ansible/user_module.html]]の stateオプションを利用してみる $ vi playbook.yml --- - hosts: all sudo: yes tasks: - name: add a new user user: name=yuji state=absent $ 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.53] changed: [192.168.43.52] 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 - yuji ユーザーが存在しない(削除されている)ことを確認 ** ansible-playbook のオプションを使ってみよう [#i8434845] - 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 - タスクの一覧表示 $ 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: [] - dry run 実行 $ ansible-playbook playbook.yml --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. PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.43.53] ok: [192.168.43.52] TASK [add a new user] ********************************************************** ok: [192.168.43.53] ok: [192.168.43.52] 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 ** playbookで変数を使ってみよう [#n94e3a07] - vars を使って変数を指定 $ vi playbook.yml --- - hosts: all sudo: yes vars: username: yuji tasks: - name: add a new user user: name={{username}} - ansible-playbook実行時にユーザーに変数を入力させる $ vi playbook.yml --- - hosts: all sudo: yes vars_prompt: username: "Enter username" tasks: - name: add a new user user: name={{username}} $ ansible-playbook playbook.yml Enter username: yuji ** yum, serviceモジュールを使ってみよう [#r1a07f16] - Webに対してApacheのインストール&起動設定 $ vi playbook.yml --- - hosts: all sudo: yes tasks: - name: add a new user user: name=yuji state=absent - 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 $ ansible-playbook playbook.yml - ブラウザ経由で 192.168.43.52 へアクセスしApacheのTest Pageが表示されることを確認 ** file, copyモジュールを使ってみよう [#f94203aa] - index.html作成 $ vi index.html <html> hello from ansible! </html> - DocumentRootのオーナーを変更 $ vi playbook.yml --- - hosts: all sudo: yes tasks: - name: add a new user user: name=yuji state=absent - 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 playbook.yml TASK [copy index.html] ********************************************************* fatal: [192.168.43.52]: FAILED! => {"changed": false, "checksum": "21f2fc90aaf25beff7f6d34f80cab32114d00ecc", "failed": true, "msg": "Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"} NO MORE HOSTS LEFT ************************************************************* [WARNING]: Could not create retry file 'playbook.retry'. [Errno 2] No such file or directory: '' PLAY RECAP ********************************************************************* 192.168.43.52 : ok=6 changed=1 unreachable=0 failed=1 192.168.43.53 : ok=2 changed=0 unreachable=0 failed=0 - libselinux-python がインストールされていないというエラーが発生したため対応 $ vi playbook.yml --- - hosts: all sudo: yes tasks: - name: add a new user user: name=yuji state=absent - name: install libselinux-python yum: name=libselinux-python state=latest - 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 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.53] ok: [192.168.43.52] TASK [install libselinux-python] *********************************************** changed: [192.168.43.52] changed: [192.168.43.53] PLAY [web] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.43.52] TASK [install apache] ********************************************************** ok: [192.168.43.52] TASK [start apache and enabled] ************************************************ ok: [192.168.43.52] TASK [change owner] ************************************************************ ok: [192.168.43.52] TASK [copy index.html] ********************************************************* changed: [192.168.43.52] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=8 changed=2 unreachable=0 failed=0 192.168.43.53 : ok=3 changed=1 unreachable=0 failed=0 - ブラウザ経由で 192.168.43.52 へアクセスし hello from ansible! が表示されることを確認 ** with_items, notify/handlersを使おう [#q4cfbe23] - PHPのインストール $ vi playbook.yml --- - hosts: all sudo: yes tasks: - name: add a new user user: name=yuji state=absent - name: install libselinux-python yum: name=libselinux-python state=latest - 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 - name: install php packages yum: name={{item}} state=latest with_items: - php - php-devel - php-mbstring - php-mysql notify: - restart apache handlers: - name: restart apache service: name=httpd state=restarted $ ansible-playbook playbook.yml &color(red){*};notifyに記述した内容に変更がない場合はhandlersは呼ばれない(実行されない) ** PHPを動作させてみよう [#e4b01d11] - PHPファイルの転送 $ vi playbook.yml --- - hosts: all sudo: yes tasks: - name: add a new user user: name=yuji state=absent - name: install libselinux-python yum: name=libselinux-python state=latest - 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 - 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 - hello.php作成 $ vi hello.php <?php echo "hello from PHP!"; $ ansible-playbook playbook.yml - ブラウザ経由で 192.168.43.52/hello.php へアクセスし hello from PHP! が表示されることを確認 ** MySQLを導入してみよう [#odea6949] $ vi playbook.yml --- - hosts: all sudo: yes tasks: - name: add a new user user: name=yuji state=absent - name: install libselinux-python yum: name=libselinux-python state=latest - 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 - 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 - 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 $ ansible-playbook playbook.yml - MySQL確認 $ ssh db $ mysql --version mysql Ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64) using readline 5.1 $ exit ** mysql_db, mysql_userを使ってみよう [#v18f47d7] $ vi playbook.yml --- - hosts: all sudo: yes tasks: - name: add a new user user: name=yuji state=absent - name: install libselinux-python yum: name=libselinux-python state=latest - 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 - 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 - 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 - name: create a database mysql_db: name=mydb state=present - name: create a user for mydb mysql_user: name=dbuser password=dbpassword priv=mydb.*:ALL state=present $ ansible-playbook playbook.yml TASK [create a database] ******************************************************* fatal: [192.168.43.53]: FAILED! => {"changed": false, "failed": true, "msg": "the python mysqldb module is required"} NO MORE HOSTS LEFT ************************************************************* [WARNING]: Could not create retry file 'playbook.retry'. [Errno 2] No such file or directory: '' PLAY RECAP ********************************************************************* 192.168.43.52 : ok=10 changed=0 unreachable=0 failed=0 192.168.43.53 : ok=6 changed=0 unreachable=0 failed=1 - python mysqldb がインストールされていないというエラーが発生したため対応 $ vi playbook.yml --- - hosts: all sudo: yes tasks: - name: add a new user user: name=yuji state=absent - name: install libselinux-python yum: name=libselinux-python state=latest - 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 - 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 - hosts: db sudo: yes tasks: - name: install mysql yum: name={{item}} state=latest with_items: - mysql-server - MySQL-python - name: start mysql and enabled service: name=mysqld state=started enabled=yes - name: create a database mysql_db: name=mydb state=present - name: create a user for mydb mysql_user: name=dbuser password=dbpassword priv=mydb.*:ALL state=present $ ansible-playbook playbook.yml - MySQL確認 $ ssh db $ mysql -u dbuser -p mydb mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mydb | | test | +--------------------+ mysql> exit $ exit