Ansibleチュヌトリアル

オヌケストラ構成管理


この実甚的なガむドでは、Ansibleを玹介しおいたす。 Ansibleのホストずしお機胜する仮想マシンたたは実マシンが必芁です。 Vagrantの環境には、このチュヌトリアルが付属しおいたす。


Ansibleは、リモヌト構成管理甚の゜フトりェア゜リュヌションです。 リモヌトマシンを蚭定できたす。 他の同様のシステムずの䞻な違いは、Ansibleが既存のSSHむンフラストラクチャを䜿甚するのに察しお、他シェフ、パペットなどは特別なPKI環境のむンストヌルを必芁ずするこずです。


このマニュアルには、次のトピックが含たれおいたす。


  1. AnsibleおよびVagrantのむンストヌル
  2. むンベントリファむル
  3. シェル、コピヌモゞュヌル、ファクトコレクション、倉数
  4. ホストのグルヌプで実行する
  5. プレむブック
  6. 䟋クラスタヌを䞊げ、ApacheずHAproxyロヌドバランサヌをむンストヌルしお構成したす
  7. ゚ラヌ凊理、ロヌルバック
  8. 構成テンプレヌト
  9. 圹割

Ansibleはいわゆるプッシュモヌドを䜿甚したす。蚭定はホストマシンから「プッシュ」されたす。 通垞、他のCMシステムは反察のこずを行いたす。ノヌドはホストマシンから構成を取埗したす。


このモヌドは、ノヌドのリモヌト構成に公的にアクセス可胜なホストマシンを必芁ずしないため、興味深いものです。 このノヌドはアクセス可胜でなければなりたせん埌で非衚瀺のノヌドも蚭定を受け取るこずができるこずがわかりたす。


Ansibleに必芁なもの


次のPythonモゞュヌルが必芁です。



Debian / Ubuntuで、次を実行したす。


sudo apt-get install python-yaml python-jinja2 python-paramiko python-crypto 

〜/ .sshにもキヌペアが必芁です。


Ansibleをむンストヌルする


゜ヌスから


develブランチは垞に安定しおいるため、䜿甚したす。 gitのむンストヌルが必芁になる堎合がありたすDebian / Ubuntuにsudo apt-get install git 。


 git clone git://github.com/ansible/ansible.git cd ./ansible 

これで、Ansible環境をダりンロヌドできたす。


 source ./hacking/env-setup 

debパッケヌゞから


 sudo apt-get install make fakeroot cdbs python-support git clone git://github.com/ansible/ansible.git cd ./ansible make deb sudo dpkg -i ../ansible_1.1_all.deb (version may vary) 

このチュヌトリアルでは、この特定の方法を䜿甚したこずを前提ずしおいたす。


Vagrantをむンストヌルする


Vagrantを䜿甚するず、仮想マシンを簡単に䜜成しおVirtualBoxで実行できたす。 Vagrantfileにはマニュアルが付属しおいたす。


Vagrantを起動するには、むンストヌルする必芁がありたす。



次のコマンドで仮想マシンを初期化したす。 「ボックス」を手動でダりンロヌドする必芁はないこずに泚意しおください。 このチュヌトリアルには、完成したVagrantfile既に含たれおおり、䜜業に必芁なすべおのものが含たれおいたす。


 vagrant up 

コヌヒヌを泚いでくださいvagrant-hostmasterを䜿甚する堎合は、rootパスワヌドを入力する必芁がありたす。 問題が発生した堎合は、Vagrantチュヌトリアルをご芧ください 。


仮想マシンにSSHキヌを远加する


続行するには、仮想マシンのauthorized_keysルヌトにキヌを远加する必芁がありたす。 これはオプションですAnsibleはsudoおよびパスワヌド認蚌を䜿甚できたすが、はるかに簡単です。


Ansibleはこのタスクに理想的であるため、䜿甚したす。 ただし、ただ䜕も説明したせん。 ただ私を信じお。


 ansible-playbook -c paramiko -i step-00/hosts step-00/setup.yml --ask-pass --sudo 

パスワヌドずしおvagrantを入力したす。 「接続が拒吊されたした」゚ラヌが発生した堎合は、ファむアりォヌルの蚭定を確認しおください。


次に、キヌをssh-agentに远加したす ssh-add 。


圚庫


次に、むンベントリファむルを準備する必芁がありたす。 デフォルトの堎所は/etc/ansible/hostsです。
ただし、別のパスを䜿甚するようにAnsibleを構成できたす。 これを行うには、環境倉数 ANSIBLE_HOSTS たたは-iフラグを䜿甚したす。


次のむンベントリファむルを䜜成したした。


 host0.example.org ansible_ssh_host=192.168.33.10 ansible_ssh_user=root host1.example.org ansible_ssh_host=192.168.33.11 ansible_ssh_user=root host2.example.org ansible_ssh_host=192.168.33.12 ansible_ssh_user=root 

ansible_ssh_hostは、接続が䜜成されるホストのIPアドレスを含む特別な倉数です。 この堎合、gem vagrant-hostmasterを䜿甚する堎合はオプションです。 たた、仮想マシンに他のアドレスをむンストヌルしお構成した堎合は、IPアドレスを倉曎する必芁がありたす。


ansible_ssh_userは、指定されたアカりントナヌザヌで接続するようAnsibleに指瀺する別の特別な倉数です。 デフォルトでは、Ansibleは珟圚のアカりント、たたは〜/ .ansible.cfg remote_user で指定された別のデフォルト倀を䜿甚したす。


確認する


Ansibleがむンストヌルされたので、すべおが機胜するこずを確認したしょう。


 ansible -m ping all -i step-01/hosts 

ここで、Ansibleは各ホストでpingモゞュヌルを実行しようずしたすモゞュヌルに぀いおは埌ほど説明したす。 出力は次のようになりたす。


 host0.example.org | success >> { "changed": false, "ping": "pong" } host1.example.org | success >> { "changed": false, "ping": "pong" } host2.example.org | success >> { "changed": false, "ping": "pong" } 

いいね 3぀のホストはすべお正垞に動䜜しおおり、Ansibleはそれらず通信できたす。


ノヌドずの通信


これで準備ができたした。 前のセクションで既におなじみのチヌムであるansible遊んでみたしょう。 このコマンドは、Ansibleがノヌドず察話するために䜿甚する3぀のコマンドの1぀です。


䜕か䟿利なこずをしたしょう


最埌のコマンドでは、 -m pingは「 pingモゞュヌルを䜿甚する」こずを意味しおいたした。 これは、Ansibleで利甚可胜な倚くのモゞュヌルの1぀です。 pingモゞュヌルping非垞に単玔で、匕数を必芁ずしたせん。 匕数を必芁ずするモゞュヌルは、 -a匕数を取埗できたす。 いく぀かのモゞュヌルを芋おみたしょう。


シェルモゞュヌル


このモゞュヌルを䜿甚するず、リモヌトホストでシェルコマンドを実行できたす。


 ansible -i step-02/hosts -m shell -a 'uname -a' host0.example.org 

出力は次のようになりたす。


 host0.example.org | success | rc=0 >> Linux host0.example.org 3.2.0-23-generic-pae #36-Ubuntu SMP Tue Apr 10 22:19:09 UTC 2012 i686 i686 i386 GNU/Linux 

簡単


コピヌモゞュヌル


copyモゞュヌルを䜿甚するず、ホストマシンからリモヌトホストにファむルをコピヌできたす。 /etc/motdを/tmpノヌドにコピヌする必芁があるず想像しおください。


 ansible -i step-02/hosts -m copy -a 'src=/etc/motd dest=/tmp/' host0.example.org 

結論


 host0.example.org | success >> { "changed": true, "dest": "/tmp/motd", "group": "root", "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "mode": "0644", "owner": "root", "size": 0, "src": "/root/.ansible/tmp/ansible-1362910475.9-246937081757218/motd", "state": "file" } 

Ansibleより正確には、ノヌドで実行されおいるコピヌモゞュヌルは、JSON圢匏の有甚な情報の束で応答したした。 埌でこれをどのように䜿甚できるかを芋おいきたす。


Ansibleには巚倧な
システムで実行できるほがすべおをカバヌするモゞュヌルのリスト 。 適切なモゞュヌルが芋぀からなかった堎合、モゞュヌルの䜜成は非垞に簡単なタスクですPythonで䜜成する必芁はありたせん。䞻なこずは、JSONを理解するこずです。


倚くのホスト、1぀のチヌム


䞊蚘はすべお玠晎らしいですが、倚くのホストを管理する必芁がありたす。 やっおみたしょう。 ノヌドに関する事実を収集し、たずえば、ノヌドにむンストヌルされおいるUbuntuのバヌゞョンを調べたいずしたす。 これは非垞に簡単です。


 ansible -i step-02/hosts -m shell -a 'grep DISTRIB_RELEASE /etc/lsb-release' all 

allは「むンベントリファむル内のすべおのホスト」を意味したす。 出力は次のようになりたす。


 host1.example.org | success | rc=0 >> DISTRIB_RELEASE=12.04 host2.example.org | success | rc=0 >> DISTRIB_RELEASE=12.04 host0.example.org | success | rc=0 >> DISTRIB_RELEASE=12.04 

より倚くの事実


簡単でシンプル。 ただし、より倚くの情報IPアドレス、RAMサむズなどが必芁な堎合、このアプロヌチはすぐに䞍䟿になるこずがありたす。 解決策は、 setupモゞュヌルを䜿甚するこずです。 圌は、ノヌドからのファクトの収集を専門ずしおいたす。


詊しおください


 ansible -i step-02/hosts -m setup host0.example.org 

答え


 "ansible_facts": { "ansible_all_ipv4_addresses": [ "192.168.0.60" ], "ansible_all_ipv6_addresses": [], "ansible_architecture": "x86_64", "ansible_bios_date": "01/01/2007", "ansible_bios_version": "Bochs" }, ---snip--- "ansible_virtualization_role": "guest", "ansible_virtualization_type": "kvm" }, "changed": false, "verbose_override": true 

出力は単玔化のために短瞮されおいたすが、この情報から倚くを孊ぶこずができたす。 特定の䜕かに興味がある堎合は、キヌをフィルタリングするこずもできたす。


たずえば、すべおのホストで䜿甚可胜なメモリ量を調べる必芁がありたす。 簡単です ansible -i step-02/hosts -m setup -a 'filter=ansible_memtotal_mb' all 


 host2.example.org | success >> { "ansible_facts": { "ansible_memtotal_mb": 187 }, "changed": false, "verbose_override": true } host1.example.org | success >> { "ansible_facts": { "ansible_memtotal_mb": 187 }, "changed": false, "verbose_override": true } host0.example.org | success >> { "ansible_facts": { "ansible_memtotal_mb": 187 }, "changed": false, "verbose_override": true } 

ノヌドは、䞊蚘で回答した間違った順序で回答したこずに泚意しおください。 Ansibleはホストず䞊行しお通信したす


ずころで、 setupモゞュヌルを䜿甚する堎合、匏filter= *を指定できたす。 シェルのように。


ホスト遞択


all 「すべおのホスト」を意味するこずがわかりたしたが、Ansibleには
ホストを遞択する他の方法の束 



ホストのグルヌプ化


むンベントリ内のホストはグルヌプ化できたす。 たずえば、 debianグルヌプ、 web-serversグルヌプ、 debianグルヌプなどを䜜成できたす。


 [debian] host0.example.org host1.example.org host2.example.org 

短瞮するこずもできたす


 [debian] host[0-2].example.org 

子グルヌプを指定する堎合は、 [groupname:children]を䜿甚しお、それに子グルヌプを远加したす。 たずえば、さたざたなLinuxディストリビュヌションがあり、次のように線成できたす。


 [ubuntu] host0.example.org [debian] host[1-2].example.org [linux:children] ubuntu debian 

倉数を蚭定する


むンベントリファむル、ホスト倉数ファむル、倉数グルヌプファむルなど、いく぀かの堎所でホストの倉数を远加できたす。


通垞、すべおの倉数をグルヌプ/ホスト倉数ファむルに蚭定したすこれに぀いおは埌で説明したす。 ただし、倚くの堎合、ホストIPアドレスを蚭定するansible_ssh_hostなど、むンベントリファむルで盎接倉数を䜿甚したす。 デフォルトでは、AnsibleはSSH経由で接続するずきにホスト名を解決したす。 ただし、ホストを初期化するずき、IPアドレスがただない堎合がありたす。 この堎合、 ansible_ssh_hostが圹立ちたす。


通垞のansibleではなく ansible-playbook ansibleを䜿甚する--extra-vars たたは-e フラグを䜿甚しお倉数を蚭定できたす。 次のステップでは、 ansible-playbookチヌムに぀いお説明したす。


ansible_ssh_port 、ごansible_ssh_port 、SSH接続ポヌトの蚭定に䜿甚されたす。


 [ubuntu] host0.example.org ansible_ssh_host=192.168.0.12 ansible_ssh_port=2222 

Ansibleは、グルヌプおよびホスト倉数ファむルで远加の倉数を探したす。 圌は、メむンむンベントリファむルがあるディレクトリ内のgroup_varsおよびhost_varsディレクトリでこれらのファむルを探したす。


Ansibleは名前でファむルを怜玢したす。 たずえば、前述のむンベントリファむルを䜿甚する堎合、Ansibleはファむル内でhost0.example.org倉数を探したす。



これらのファむルが存圚しない堎合は䜕も起こりたせんが、存圚する堎合は䜿甚されたす。


モゞュヌル、むンベントリ、および倉数に粟通したので、最埌にPlaybookでのAnsibleの真の力に぀いお調べたしょう。


Playbook Ansible


プレむブックの抂念は非垞にシンプルです。これは、Ansibleナヌティリティで䜿甚したものず同様のAnsibleコマンドタスク、タスクの単なるコレクションです。 これらのタスクは、特定のノヌド/グルヌプのセットを察象ずしおいたす。


Apacheの䟋別名 "Hello World" Insible


むンベントリファむルが次のように芋えるずいう仮定を続けたす hostsず呌びたしょう


 [web] host1.example.org 

すべおのホストはDebianベヌスのシステムです。


泚 ansible_ssh_hostを䜿甚しお実際のホストIPアドレスを蚭定できるこずを思い出しおくださいそしお、この挔習でこれを行いたす。 むンベントリを倉曎しお、実際のホスト名を䜿甚するこずもできたす。 いずれにしおも、安党に実隓できるマシンを䜿甚しおください。 たた、実際のホストでは、 ansible_ssh_user=rootを远加しお、異なるデフォルト蚭定での朜圚的な問題を回避したす。


webグルヌプのマシンにApacheをむンストヌルするプレむブックを䜜成したしょう。


 - hosts: web tasks: - name: Installs apache web server apt: pkg=apache2 state=installed update_cache=true 

適切なAnsibleモゞュヌルを䜿甚しお䜕をしたいのかを蚀うだけです。 ここでは、Debianパッケヌゞをむンストヌルできるaptモゞュヌルを䜿甚したす。 たた、このモゞュヌルにキャッシュの曎新を䟝頌したす。


このタスクには名前が必芁です。 これは必須ではありたせんが、利䟿性のために望たしいものです。


たあ、党䜓的にはずおも簡単でした これで、プレむブックを開始できたす apache.ymlず呌びたしょう


 ansible-playbook -i step-04/hosts -l host1.example.org step-04/apache.yml 

ここで、 step-04/hostsはむンベントリファむルです。- -lをホストで実行するように制限したす。
そしおapache.ymlは私たちのプレむブックです。


コマンドを実行するず、次のような出力が衚瀺されたす。


 PLAY [web] ********************* GATHERING FACTS ********************* ok: [host1.example.org] TASK: [Installs apache web server] ********************* changed: [host1.example.org] PLAY RECAP ********************* host1.example.org : ok=2 changed=1 unreachable=0 failed=0 

泚 cowsayむンストヌルしおいる堎合、牛が通り過ぎるこずに気付くかもしれたせん:-)気に入らなければ、次のように無効にできたす export ANSIBLE_NOCOWS="1" 。


行ごずに出力を分析したしょう。


 PLAY [web] ********************* 

Ansibleは、プレむはwebグルヌプで実行されるこずを瀺しおいweb 。 Playは、Ansibleホスト関連の呜什のコレクションです。 プレむブックに別の-host: blahがある堎合、それも衚瀺されたすただし、最初のプレむが完了した埌。


 GATHERING FACTS ********************* ok: [host1.example.org] 

setupモゞュヌルを䜿甚したずきのこずを芚えおいたすか 各再生の前に、Ansibleは各ホストでそれを実行し、ファクトを収集したす。 これが必芁ない堎合たずえば、ホストに関する情報が必芁ないため、ホスト行gather_facts: no䞋に tasks:ず同じレベルで gather_facts: no远加できたす。


 TASK: [Installs apache web server] ********************* changed: [host1.example.org] 

これが最も重芁なこずです。最初で唯䞀のタスクが起動され、 changedず衚瀺されおいるため、 host1.example.org䜕かを倉曎したこずがhost1.example.orgたす。


 PLAY RECAP ********************* host1.example.org : ok=2 changed=1 unreachable=0 failed=0 

最埌に、Ansibleは2぀のタスクが完了し、そのうちの1぀がホスト䞊の䜕かを倉曎したしたこれはApacheタスクでした。セットアップモゞュヌルは䜕も倉曎したせん。


これをもう䞀床実行しお、䜕が起こるか芋おみたしょう。


 $ ansible-playbook -i step-04/hosts -l host1.example.org step-04/apache.yml PLAY [web] ********************* GATHERING FACTS ********************* ok: [host1.example.org] TASK: [Installs apache web server] ********************* ok: [host1.example.org] PLAY RECAP ********************* host1.example.org : ok=2 changed=0 unreachable=0 failed=0 

倉曎された倀は「0」に等しくなりたした。 これは完党に正垞であり、Ansibleの䞻な機胜の1぀です。プレむブックは、䜕かするこずがある堎合にのみ䜕かを実行したす。 これは、 べき等性ず呌ばれたす。 これは、プレむブックを䜕回でも実行できるこずを意味したすが、最終的には同じ状態のマシンになりたす shellモゞュヌルに倢䞭にならなくおも、Ansibleはそれ以䞊䜕もできたせん。


Apache Suiteの改善


Apacheをむンストヌルしたした。仮想ホストを蚭定したしょう。


プレむブックの改善


サヌバヌに必芁な仮想ホストは1぀だけですが、デフォルトをより具䜓的なものに倉曎する必芁がありたす。 したがっお、珟圚の仮想ホストを削陀し、仮想ホストを送信し、アクティブにしお、Apacheを再起動する必芁がありたす。


filesずいうディレクトリを䜜成し、host1.example.orgの蚭定を远加しお、 awesome-appずいう名前を付けたしょう。


 <VirtualHost *:80> DocumentRoot /var/www/awesome-app Options -Indexes ErrorLog /var/log/apache2/error.log TransferLog /var/log/apache2/access.log </VirtualHost> 

これで、プレむブックが少し無効になり、完了です。


 - hosts: web tasks: - name: Installs apache web server apt: pkg=apache2 state=installed update_cache=true - name: Push default virtual host configuration copy: src=files/awesome-app dest=/etc/apache2/sites-available/ mode=0640 - name: Deactivates the default virtualhost command: a2dissite default - name: Deactivates the default ssl virtualhost command: a2dissite default-ssl - name: Activates our virtualhost command: a2ensite awesome-app notify: - restart apache handlers: - name: restart apache service: name=apache2 state=restarted 

行こう


 $ ansible-playbook -i step-05/hosts -l host1.example.org step-05/apache.yml PLAY [web] ********************* GATHERING FACTS ********************* ok: [host1.example.org] TASK: [Installs apache web server] ********************* ok: [host1.example.org] TASK: [Push default virtual host configuration] ********************* changed: [host1.example.org] TASK: [Deactivates the default virtualhost] ********************* changed: [host1.example.org] TASK: [Deactivates the default ssl virtualhost] ********************* changed: [host1.example.org] TASK: [Activates our virtualhost] ********************* changed: [host1.example.org] NOTIFIED: [restart apache] ********************* changed: [host1.example.org] PLAY RECAP ********************* host1.example.org : ok=7 changed=5 unreachable=0 failed=0 

かっこいい 考えおみれば、私たちは少し先を行っおいたす。 Apacheを再起動する前に蚭定の正確性を確認する必芁はありたすか 構成に゚ラヌが含たれおいる堎合にサヌビスを䞭断しないようにするため。


構成゚ラヌが発生した堎合の再起動


Apacheをむンストヌルし、仮想ホストを倉曎しおサヌバヌを再起動したした。 しかし、蚭定が正しい堎合にのみサヌバヌを再起動したい堎合はどうでしょうか


問題がある堎合はロヌルバックしたす


Ansibleにはクヌルな機胜が含たれおいたす。䜕か問題が発生するず、すべおの凊理が停止したす。 蚭定が有効でない堎合、この機胜を䜿甚しおプレむブックを停止したす。


awesome-app仮想ホスト構成ファむルを倉曎しお、砎壊しおみたしょう。


  <VirtualHost *:80> RocumentDoot /var/www/awesome-app Options -Indexes ErrorLog /var/log/apache2/error.log TransferLog /var/log/apache2/access.log </VirtualHost> 

前にも蚀ったように、タスクを完了できない堎合、凊理は停止したす。 そのため、サヌバヌを再起動する前に構成の有効性を確認する必芁がありたす。 たた、仮想ホストを远加しおデフォルトの仮想ホストを削陀するこずから始めたす。したがっお、その埌の再起動サヌバヌ䞊で盎接実行される可胜性がありたすによっおApacheが壊れるこずはありたせん。


最初にこれを行う必芁がありたした。 このプレむブックを既に開始しおいるため、デフォルトの仮想ホストはすでに非アクティブ化されおいたす。 問題ありたせんこのプレむブックは他の眪のないホストでも䜿甚できるので、保護したしょう。


 - hosts: web tasks: - name: Installs apache web server apt: pkg=apache2 state=installed update_cache=true - name: Push future default virtual host configuration copy: src=files/awesome-app dest=/etc/apache2/sites-available/ mode=0640 - name: Activates our virtualhost command: a2ensite awesome-app - name: Check that our config is valid command: apache2ctl configtest - name: Deactivates the default virtualhost command: a2dissite default - name: Deactivates the default ssl virtualhost command: a2dissite default-ssl notify: - restart apache handlers: - name: restart apache service: name=apache2 state=restarted 

行こう


 $ ansible-playbook -i step-06/hosts -l host1.example.org step-06/apache.yml PLAY [web] ********************* GATHERING FACTS ********************* ok: [host1.example.org] TASK: [Installs apache web server] ********************* ok: [host1.example.org] TASK: [Push future default virtual host configuration] ********************* changed: [host1.example.org] TASK: [Activates our virtualhost] ********************* changed: [host1.example.org] TASK: [Check that our config is valid] ********************* failed: [host1.example.org] => {"changed": true, "cmd": ["apache2ctl", "configtest"], "delta": "0:00:00.045046", "end": "2013-03-08 16:09:32.002063", "rc": 1, "start": "2013-03-08 16:09:31.957017"} stderr: Syntax error on line 2 of /etc/apache2/sites-enabled/awesome-app: Invalid command 'RocumentDoot', perhaps misspelled or defined by a module not included in the server configuration stdout: Action 'configtest' failed. The Apache error log may have more information. FATAL: all hosts have already failed -- aborting PLAY RECAP ********************* host1.example.org : ok=4 changed=2 unreachable=0 failed=1 

お気づきのように、 apache2ctlぱラヌコヌド1を返したす。Ansibleはこれを認識しお動䜜を停止したす。 いいね


うヌん、いや、倧したこずはない...ずにかく仮想ホストが远加された。 その埌の再起動の詊行で、Apacheは構成のオンずオフを誓いたす。 したがっお、゚ラヌをキャッチしお䜜業状態に戻る方法が必芁です。


コメント翻蚳者コメントの@clickfreak habrayuzerは、Ansible 2.xの特別な機胜を芋るよう提案しおいたす。


条件の䜿甚


Apacheをむンストヌルし、仮想ホストを远加しおサヌバヌを再起動したした。 ただし、䜕か問題が発生した堎合は、䜜業状態に戻りたいず考えおいたす。


問題の返品


ここには魔法はありたせん。 過去の間違いはAnsibleのせいではありたせん。 これはバックアップシステムではなく、過去の状況に察するすべおを拒吊する方法を知りたせん。 プレむブックの安党はあなたの責任です。 Ansibleは、 a2ensite awesome-app効果を元に戻す方法を知りたせん。


前述のように、タスクを完了できない堎合、凊理は停止したすが、゚ラヌを受け入れるこずができたす これを行う必芁がありたす 。 したがっお、゚ラヌが発生した堎合に凊理を続行したすが、すべおを動䜜状態に戻したす。


 - hosts: web tasks: - name: Installs apache web server apt: pkg=apache2 state=installed update_cache=true - name: Push future default virtual host configuration copy: src=files/awesome-app dest=/etc/apache2/sites-available/ mode=0640 - name: Activates our virtualhost command: a2ensite awesome-app - name: Check that our config is valid command: apache2ctl configtest register: result ignore_errors: True - name: Rolling back - Restoring old default virtualhost command: a2ensite default when: result|failed - name: Rolling back - Removing our virtualhost command: a2dissite awesome-app when: result|failed - name: Rolling back - Ending playbook fail: msg="Configuration file is not valid. Please check that before re-running the playbook." when: result|failed - name: Deactivates the default virtualhost command: a2dissite default - name: Deactivates the default ssl virtualhost command: a2dissite default-ssl notify: - restart apache handlers: - name: restart apache service: name=apache2 state=restarted 

registerキヌワヌドは、 apache2ctl configtest exitの出力を曞き蟌みたす
status、stdout、stderr、...、およびwhen: result|failed倉数に
 result ステヌタスが倱敗したした。


行こう


 $ ansible-playbook -i step-07/hosts -l host1.example.org step-07/apache.yml PLAY [web] ********************* GATHERING FACTS ********************* ok: [host1.example.org] TASK: [Installs apache web server] ********************* ok: [host1.example.org] TASK: [Push future default virtual host configuration] ********************* ok: [host1.example.org] TASK: [Activates our virtualhost] ********************* changed: [host1.example.org] TASK: [Check that our config is valid] ********************* failed: [host1.example.org] => {"changed": true, "cmd": ["apache2ctl", "configtest"], "delta": "0:00:00.051874", "end": "2013-03-10 10:50:17.714105", "rc": 1, "start": "2013-03-10 10:50:17.662231"} stderr: Syntax error on line 2 of /etc/apache2/sites-enabled/awesome-app: Invalid command 'RocumentDoot', perhaps misspelled or defined by a module not included in the server configuration stdout: Action 'configtest' failed. The Apache error log may have more information. ...ignoring TASK: [Rolling back - Restoring old default virtualhost] ********************* changed: [host1.example.org] TASK: [Rolling back - Removing our virtualhost] ********************* changed: [host1.example.org] TASK: [Rolling back - Ending playbook] ********************* failed: [host1.example.org] => {"failed": true} msg: Configuration file is not valid. Please check that before re-running the playbook. FATAL: all hosts have already failed -- aborting PLAY RECAP ********************* host1.example.org : ok=7 changed=4 unreachable=0 failed=1 

すべおが正垞に機胜しおいるようです。 Apacheを再起動しおみたしょう。


 $ ansible -i step-07/hosts -m service -a 'name=apache2 state=restarted' host1.example.org host1.example.org | success >> { "changed": true, "name": "apache2", "state": "started" } 

これで、Apacheは構成゚ラヌから保護されたした。 倉数はほずんどどこでも䜿甚できるため、このプレむブックは他の堎合のApacheに䜿甚できるこずを忘れないでください。 䞀床曞いお、どこでも䜿甚したす。


Git


Apache, . git .


git


, , , . git . - . , ansible-pull .


, . PHP, libapache2-mod-php5 . git , , , git .


:


  ... - name: Installs apache web server apt: pkg=apache2 state=installed update_cache=true - name: Installs php5 module apt: pkg=libapache2-mod-php5 state=installed - name: Installs git apt: pkg=git state=installed ... 

Ansible . , :


 - hosts: web tasks: - name: Updates apt cache apt: update_cache=true - name: Installs necessary packages apt: pkg={{ item }} state=latest with_items: - apache2 - libapache2-mod-php5 - git - name: Push future default virtual host configuration copy: src=files/awesome-app dest=/etc/apache2/sites-available/ mode=0640 - name: Activates our virtualhost command: a2ensite awesome-app - name: Check that our config is valid command: apache2ctl configtest register: result ignore_errors: True - name: Rolling back - Restoring old default virtualhost command: a2ensite default when: result|failed - name: Rolling back - Removing out virtualhost command: a2dissite awesome-app when: result|failed - name: Rolling back - Ending playbook fail: msg="Configuration file is not valid. Please check that before re-running the playbook." when: result|failed - name: Deploy our awesome application git: repo=https://github.com/leucos/ansible-tuto-demosite.git dest=/var/www/awesome-app tags: deploy - name: Deactivates the default virtualhost command: a2dissite default - name: Deactivates the default ssl virtualhost command: a2dissite default-ssl notify: - restart apache handlers: - name: restart apache service: name=apache2 state=restarted 

:


 $ ansible-playbook -i step-08/hosts -l host1.example.org step-08/apache.yml PLAY [web] ********************* GATHERING FACTS ********************* ok: [host1.example.org] TASK: [Updates apt cache] ********************* ok: [host1.example.org] TASK: [Installs necessary packages] ********************* changed: [host1.example.org] => (item=apache2,libapache2-mod-php5,git) TASK: [Push future default virtual host configuration] ********************* changed: [host1.example.org] TASK: [Activates our virtualhost] ********************* changed: [host1.example.org] TASK: [Check that our config is valid] ********************* changed: [host1.example.org] TASK: [Rolling back - Restoring old default virtualhost] ********************* skipping: [host1.example.org] TASK: [Rolling back - Removing out virtualhost] ********************* skipping: [host1.example.org] TASK: [Rolling back - Ending playbook] ********************* skipping: [host1.example.org] TASK: [Deploy our awesome application] ********************* changed: [host1.example.org] TASK: [Deactivates the default virtualhost] ********************* changed: [host1.example.org] TASK: [Deactivates the default ssl virtualhost] ********************* changed: [host1.example.org] NOTIFIED: [restart apache] ********************* changed: [host1.example.org] PLAY RECAP ********************* host1.example.org : ok=10 changed=8 unreachable=0 failed=0 

http://192.168.33.11 .


tags: deploy . , . , . . , "deploy" — , . , :


$ ansible-playbook -i step-08/hosts -l host1.example.org step-08/apache.yml -t deploy
X11 forwarding request failed on channel 0


PLAY [web] * ****


GATHERING FACTS * ****
ok: [host1.example.org]


TASK: [Deploy our awesome application] * ****
changed: [host1.example.org]


PLAY RECAP * ****
host1.example.org: ok=2 changed=1 unreachable=0 failed=0


-


-. .


inventory


, - , . inventory:


 [web] host1.example.org ansible_ssh_host=192.168.33.11 ansible_ssh_user=root host2.example.org ansible_ssh_host=192.168.33.12 ansible_ssh_user=root [haproxy] host0.example.org ansible_ssh_host=192.168.33.10 ansible_ssh_user=root 

, ansible_ssh_host IP, . /etc/hosts ( ).


-


. :


 $ ansible-playbook -i step-09/hosts step-09/apache.yml PLAY [web] ********************* GATHERING FACTS ********************* ok: [host2.example.org] ok: [host1.example.org] TASK: [Updates apt cache] ********************* ok: [host1.example.org] ok: [host2.example.org] TASK: [Installs necessary packages] ********************* ok: [host1.example.org] => (item=apache2,libapache2-mod-php5,git) changed: [host2.example.org] => (item=apache2,libapache2-mod-php5,git) TASK: [Push future default virtual host configuration] ********************* ok: [host1.example.org] changed: [host2.example.org] TASK: [Activates our virtualhost] ********************* changed: [host2.example.org] changed: [host1.example.org] TASK: [Check that our config is valid] ********************* changed: [host2.example.org] changed: [host1.example.org] TASK: [Rolling back - Restoring old default virtualhost] ********************* skipping: [host1.example.org] skipping: [host2.example.org] TASK: [Rolling back - Removing out virtualhost] ********************* skipping: [host1.example.org] skipping: [host2.example.org] TASK: [Rolling back - Ending playbook] ********************* skipping: [host1.example.org] skipping: [host2.example.org] TASK: [Deploy our awesome application] ********************* ok: [host1.example.org] changed: [host2.example.org] TASK: [Deactivates the default virtualhost] ********************* changed: [host1.example.org] changed: [host2.example.org] TASK: [Deactivates the default ssl virtualhost] ********************* changed: [host2.example.org] changed: [host1.example.org] NOTIFIED: [restart apache] ********************* changed: [host1.example.org] changed: [host2.example.org] PLAY RECAP ********************* host1.example.org : ok=10 changed=5 unreachable=0 failed=0 host2.example.org : ok=10 changed=8 unreachable=0 failed=0 

, , -l host1.example.org . , -l . , web .


web , , , , : -l firsthost:secondhost:... .


-, .


パタヌン


haproxy . , apache. , - haproxy . どうやっおやるの


HAProxy


Ansible Jinja2 , Python. Jinja2- , Ansible'.


, inventory_name , , {{ inventory_hostname }} Jinja2-. , IP- ethernet- ( Ansible setup ), {{ ansible_eth1['ipv4']['address'] }} .


Jinja2 , .


templates/ Jinja- . haproxy.cfg.j2 . .j2 , .


 global daemon maxconn 256 defaults mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms listen cluster bind {{ ansible_eth1['ipv4']['address'] }}:80 mode http stats enable balance roundrobin {% for backend in groups['web'] %} server {{ hostvars[backend]['ansible_hostname'] }} {{ hostvars[backend]['ansible_eth1']['ipv4']['address'] }} check port 80 {% endfor %} option httpchk HEAD /index.php HTTP/1.0 

.


-, {{ ansible_eth1['ipv4']['address'] }} IP eth1.


. -. [web] , backend . . hostvars , (, IP, ) .


, . , . , [web] .


HAProxy playbook


最も難しい郚分は埌ろにありたす。 HAproxy :


 - hosts: haproxy tasks: - name: Installs haproxy load balancer apt: pkg=haproxy state=installed update_cache=yes - name: Pushes configuration template: src=templates/haproxy.cfg.j2 dest=/etc/haproxy/haproxy.cfg mode=0640 owner=root group=root notify: - restart haproxy - name: Sets default starting flag to 1 lineinfile: dest=/etc/default/haproxy regexp="^ENABLED" line="ENABLED=1" notify: - restart haproxy handlers: - name: restart haproxy service: name=haproxy state=restarted 

, ? : template . , copy . haproxy .



 . inventory , . , , , haproxy- -. , .


 $ ansible-playbook -i step-10/hosts step-10/apache.yml step-10/haproxy.yml PLAY [web] ********************* GATHERING FACTS ********************* ok: [host1.example.org] ok: [host2.example.org] TASK: [Updates apt cache] ********************* ok: [host1.example.org] ok: [host2.example.org] TASK: [Installs necessary packages] ********************* ok: [host1.example.org] => (item=apache2,libapache2-mod-php5,git) ok: [host2.example.org] => (item=apache2,libapache2-mod-php5,git) TASK: [Push future default virtual host configuration] ********************* ok: [host2.example.org] ok: [host1.example.org] TASK: [Activates our virtualhost] ********************* changed: [host1.example.org] changed: [host2.example.org] TASK: [Check that our config is valid] ********************* changed: [host1.example.org] changed: [host2.example.org] TASK: [Rolling back - Restoring old default virtualhost] ********************* skipping: [host1.example.org] skipping: [host2.example.org] TASK: [Rolling back - Removing out virtualhost] ********************* skipping: [host1.example.org] skipping: [host2.example.org] TASK: [Rolling back - Ending playbook] ********************* skipping: [host1.example.org] skipping: [host2.example.org] TASK: [Deploy our awesome application] ********************* ok: [host2.example.org] ok: [host1.example.org] TASK: [Deactivates the default virtualhost] ********************* changed: [host1.example.org] changed: [host2.example.org] TASK: [Deactivates the default ssl virtualhost] ********************* changed: [host2.example.org] changed: [host1.example.org] NOTIFIED: [restart apache] ********************* changed: [host2.example.org] changed: [host1.example.org] PLAY RECAP ********************* host1.example.org : ok=10 changed=5 unreachable=0 failed=0 host2.example.org : ok=10 changed=5 unreachable=0 failed=0 PLAY [haproxy] ********************* GATHERING FACTS ********************* ok: [host0.example.org] TASK: [Installs haproxy load balancer] ********************* changed: [host0.example.org] TASK: [Pushes configuration] ********************* changed: [host0.example.org] TASK: [Sets default starting flag to 1] ********************* changed: [host0.example.org] NOTIFIED: [restart haproxy] ********************* changed: [host0.example.org] PLAY RECAP ********************* host0.example.org : ok=5 changed=4 unreachable=0 failed=0 

. http://192.168.33.10/ . ! HAproxy: http://192.168.33.10/haproxy?stats .



, , . .


Ansible . ansible_ssh_host inventory, , host_vars group_vars .


HAProxy


HAProxy , . , , HAProxy .


( 0 256). , . , .


.


Group-


haproxy group_vars. , haproxy .


group_vars/haproxy inventory. , . web, group_vars/web .


 haproxy_check_interval: 3000 haproxy_stats_socket: /tmp/sock 

. , , - . ( Python dict) :


 haproxy: check_interval: 3000 stats_socket: /tmp/sock 

. . .



, host_vars . host_vars/host1.example.com :


 haproxy_backend_weight: 100 

host_vars/host2.example.com :


 haproxy_backend_weight: 150 

haproxy_backend_weight group_vars/web , -:
host_vars group_vars .



, .


 global daemon maxconn 256 {% if haproxy_stats_socket %} stats socket {{ haproxy_stats_socket }} {% endif %} defaults mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms listen cluster bind {{ ansible_eth1['ipv4']['address'] }}:80 mode http stats enable balance roundrobin {% for backend in groups['web'] %} server {{ hostvars[backend]['ansible_hostname'] }} {{ hostvars[backend]['ansible_eth1']['ipv4']['address'] }} check inter {{ haproxy_check_interval }} weight {{ hostvars[backend]['haproxy_backend_weight'] }} port 80 {% endfor %} option httpchk HEAD /index.php HTTP/1.0 

{% if ... ? , . , - haproxy_stats_socket ( --extra-vars="haproxy_stats_sockets=/tmp/sock" ), .


, !


:


 ansible-playbook -i step-11/hosts step-11/haproxy.yml 

, apache, . . haproxy:


 - hosts: web - hosts: haproxy tasks: - name: Installs haproxy load balancer apt: pkg=haproxy state=installed update_cache=yes - name: Pushes configuration template: src=templates/haproxy.cfg.j2 dest=/etc/haproxy/haproxy.cfg mode=0640 owner=root group=root notify: - restart haproxy - name: Sets default starting flag to 1 lineinfile: dest=/etc/default/haproxy regexp="^ENABLED" line="ENABLED=1" notify: - restart haproxy handlers: - name: restart haproxy service: name=haproxy state=restarted 

ほら - . . Ansible web . , haproxy . , Ansible , ansible_eth1 .


!


, , ! . — , . ,
Ansible . — : B A. B, A.



«» Ansible: . , . , , . . "convention over configuration".


:


 roles | |_some_role | |_files | | | |_file1 | |_... | |_templates | | | |_template1.j2 | |_... | |_tasks | | | |_main.yml | |_some_other_file.yml | |_ ... | |_handlers | | | |_main.yml | |_some_other_file.yml | |_ ... | |_vars | | | |_main.yml | |_some_other_file.yml | |_ ... | |_meta | |_main.yml |_some_other_file.yml |_ ... 

.


main.yml . , . .


vars meta . vars , , . . , , — . , , — . «» (, ) . . . Ansible .


meta , . roles .


Apache


, apache .


:




:


 mkdir -p step-12/roles/apache/{tasks,handlers,files} 

apache.yml main.yml . :


 - name: Updates apt cache apt: update_cache=true - name: Installs necessary packages apt: pkg={{ item }} state=latest with_items: - apache2 - libapache2-mod-php5 - git ... - name: Deactivates the default ssl virtualhost command: a2dissite default-ssl notify: - restart apache 

, .
apache.yml tasks: handlers: .


files/ templates/ . , Ansible , .



step-12/roles/apache/handlers/main.yml :


 - name: restart apache service: name=apache2 state=restarted 


:


 cp step-11/files/awesome-app step-12/roles/apache/files/ 

apache . .



. site.yml , . haproxy :


 - hosts: web roles: - { role: apache } - hosts: haproxy roles: - { role: haproxy } 

. haproxy:


 mkdir -p step-12/roles/haproxy/{tasks,handlers,templates} cp step-11/templates/haproxy.cfg.j2 step-12/roles/haproxy/templates/ 

templates/ .


?:


 ansible-playbook -i step-12/hosts step-12/site.yml 

, "PLAY RECAP":


 host0.example.org : ok=5 changed=2 unreachable=0 failed=0 host1.example.org : ok=10 changed=5 unreachable=0 failed=0 host2.example.org : ok=10 changed=5 unreachable=0 failed=0 

, site.yml . -? ! limit-:


 ansible-playbook -i step-12/hosts -l web step-12/site.yml 

.


( : . ).



Source: https://habr.com/ru/post/J305400/


All Articles