入門編TweetAnsible便利ですよね。一度設定ファイルを作ってしまえばあとはコマンド一発で同様のサーバ環境が作れます。対象サーバも一度に何台でもまとめて設定できるのも便利。最近では人間が手作業で実行する日々の運用でも活躍するシーンが出てきました。サーバのみならずクライアント環境に対しても利用できちゃいます。Ansibleのようなソフトウェアを構成管理ツールと呼びます。同様の物にChefやPuppetなど色々ありますが、管理対象のマシンはPythonが入っていれば他に余計なソフトウェア(Agent)をインストールしなくて良いのがAnsibleの特徴でもあり良いところです。いうわけで、ここしばらくサボって使わないでいたらすっかり使い方を忘れてしまったので再入門と相成りました。以前はVagrantとセットで利用していたのですが、今回はmacOS上でPlaybookを実行し、Linuxサーバの構成管理を行います。文量が多くなってしまったので何回かに分けてお話する予定です。今回は基本的な利用方法になります。Lightsail上にインスタンスを作成、AmazonLinuxを選択しました。構成管理を行うサーバにはPythonがインストールされており、SSHでログインできるユーザーを作成すれば準備完了です。Python3yum等で適当に3系をインストールします。python3/usr/bin/python3今回は3.6.8が入りました。Pythonがインストールされたパスをメモして置いてください。SSHでログイン可能なユーザーを作成AWSでインスタンスを作成した際のデフォルトユーザーであるec2-userを利用しても良いのですが、Ansible専用ユーザーを作成しておくのが安全です。今回はansiblemanという名前のユーザーを作成します。管理者権限のあるユーザーで、新規にユーザーを作成しします。ansiblemanSSHでログインできるようPlaybookを実行する端末で作成した公開鍵を所定の場所に保存します。パーミッションの設定をお忘れなく。exitAnsible内でsudoコマンドを利用する場合はvisudoで以下の行を追加しておきます(管理者権限のあるユーザーで実行してください)。ALLパスワードの入力を必須にすることもできますし、wheelグループに追加する方法でも大丈夫です。このあたりの設定はお好みでどうぞ。パスワードの入力を必須にするとAnsibleでもパスワードの管理を行う必要が出てくるため、ちょっと面倒なことになるのでご注意を。ここまで終わったら、手元のTerminalなどからログインすることが可能か試してみてください。Playbookを実行する側(macOS)今回はmacOS上にインストールします。HomeBrewで一発です。ansible今回入ったのは2.8.0でした。(clang-1001.0.46.4)]その他のOSでのインストール方法はAnsibleの公式サイトを参照ください。yumやdnfなどの構成管理ツールを利用するケースが多く手軽に入れることができます。Documentationhttps://docs.ansible.com/ansible/latest/installation_guide/intro_installation.htmldocs.ansible.com以上で準備は整いました。最初の一歩まず最初に接続先情報の定義を行い、Ansibleから無事に接続できるかテストを行います。適当なディレクトリを作成し、その中にAnsibleの設定ファイルansible.cfgを準備します。ゼロから書くのは大変面倒なのでGitHub上にあるAnsibleのリポジトリから雛形をもらってきます。https://raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg適当なエディタでansible.cfgを開き、以下のinventory=から始まる行を追加します。右辺の値の名称は何でも良いです。./inventory接続先のサーバ情報の定義ansible.cfgのinventoryで指定したディレクトリを作成し、その中に適当な名前のファイルを作成します。ここではproductionという名前で作成しました。productionこのときファイルに.iniなどの拡張子を付けたくなりますが、付けてはなりません。(ハマりましたw)ホスト情報このファイルへ実際にPlaybookで管理したいサーバの情報をini形式で定義していきます。[servers]example.com[servers]とある箇所はサーバをグルーピングするための物です。名称は何でも構いません。example.comとある箇所はIPアドレスでもOKです。以下のように複数のホストやグループを同時に定義することもできます。[web]web1.example.comweb2.example.comweb3.example.com[db]master.db.example.comslave1.db.example.comslave2.db.example.com接続情報ホスト情報の下のあたりに、今度は接続情報を記述します。内容は見ての通りでポート番号やユーザー名、秘密鍵の場所、最後にPythonのパスを定義しておきます。[servers]example.com[servers:vars]ansible_port=22ansible_ssh_user=ansiblemanansible_ssh_private_key_file=~/.ssh/id_rsaansible_python_interpreter=/usr/bin/python3複数のグループに対して、接続情報をまとめて定義したい場合は[servers:vars]を[all:vars]とします。[web]web.example.com[db]db.example.com[all:vars]ansible_port=22ansible_ssh_user=ansiblemanansible_ssh_private_key_file=~/.ssh/id_rsaansible_python_interpreter=/usr/bin/python3もちろんwebとdbでユーザーが異なる場合は、それぞれ定義してやります。動作テストしてみるここまでの設定が正しく動くか実験してみます。現在の構成は以下の通り。productionファイルproductionの内容は以下です。[servers]example.com[servers:vars]ansible_port=22ansible_ssh_user=ansiblemanansible_ssh_private_key_file=~/.ssh/id_rsaansible_python_interpreter=/usr/bin/python3ここまで用意できたらいざ動作テストです。以下のmacOS上で次のコマンドを実行。環境によっては起動や初期化でちょっと時間がかかります。Pythonで作られていることもあり動作速度はあまり期待しない方が良いです。"pong"}serversはinventory/productionで定義したグループの名前です。指定したグループ内のサーバすべてにpingを実行するコマンドになります。上記のようにホスト名の横にSUCCESSと表示されれば成功です。何らかの設定を間違えている場合はこの段階でエラーや警告が表示されます。pingとしますカレントディレクトリにansible.cfgが存在している状態で実行してくださいはじめてのPlayBookansibleコマンドで各種設定を行うことも出来るのですが、まとまった処理を行う場合には「Playbook」と呼ばれる機能を利用します。Playbookは実行したい処理をYAMLで定義したもので、一定のルールに従って記述するだけですので、慣れてしまえばプログラムほど難しくはありません。HelloWorldでは簡単なPlaybookを作成してみます。ansible1stディレクトリ直下にplaybook.ymlという名前で以下の内容のファイルを作成します。ansible.logコマンドを実行します。nameはメモのような物で実際の処理とは関係ありませんが、Ansibleにより処理が成功したか失敗したか表示されるタイミングで利用されますので人間が見てわかるものを記入します。呼ばれている部分です。様々な機能のモジュールが最初から用意されており、必要に応じて使い分けていきます。ここではLinux上のシェルで動作させるコマンドをそのまま記述します。同様の機能にcommandモジュールがありますがこちらはリダイレクトやパイプの利用ができません(不便な反面、安全と言えます)。YAMLは意外とフォーマットが細かく決まっているので記述する際には注意してください。実行する現在の構成は以下の通りです。productionでは先ほど作成したplaybook.ymlを実行してみます。実行するコマンドはansibleではなくansible-playbookになります。結果表示は見たままで、すべてのタスクでfailedなどの異常が出ていないかを見ます。実行結果も確認しておきます。サーバを覗いてホームディレクトリにansible.logが作成されていたら成功です。JSTPlaybookは一度だけ実行する物もあれば、何度も実行する物もあります。後者の場合、なるべくすべてのタスクがokになることを目指してPlaybookを作成するのがAnsibleの流儀のようです。ここまでできればあとは応用です。この先はいかにPlaybookの書き方をマスターするかというお話になります。(初級編)に非常に分かりやすくまとめられていますので、こちらを一読ください。ここでは主要なところだけかいつまんでまとめておきます。YAMLはもう理解している場合には次の項目へスキップしてください。基本的にYAMLのパーサーが自動的に判定してくれますので、特に意識する必要はありません。文字列として扱いたい場合にはダブルコーテーションなどの引用符で囲ってあげる必要があります。[+-]hh:mm)これら以外は文字列として認識されます。引用符「’」や二重引用符「”」で囲むと、強制的に文字列として認識されます。先頭にハイフン(-)をつけると「配列」になります。パイナップル半角スペース2個分のインデントを設けることでネスト(入れ子)することができます。ネストする際には空の要素が先頭に必要にる点に注意です。パイナップル注意点としては、以下のような書き方は、意図しない動きになります。前者は空の要素もネストされており、後者は空のネストが無いパターンです。errorにはならず単なる文字列として扱われますので、誤りに気が付きにくい箇所です。ハッシュコロン(:)でキーと値を挟むことでハッシュ(連想配列)になります。コロンのあとにはスペース1個以上を書きます。Pineappleハッシュもインデントすればネスト(入れ子)が可能です。配列の要素としてハッシュを持つには以下のようにします。Pineappleここまで来るとどこかで見たような形式になってきましたねwインデントYAMLはインデントの制約が非常に厳しいです。インデントはスペースのみでタブの利用はできません。通常スペース2個で1インデントとなります。errorとなってしまいます。試しに以下のようにわざとスペース1個分ずらして実行してみます。ansible.log実行すると無事に?エラーが発生し処理を行うことができませんでした。hereansibleではなく何らかのプログラミング言語のパーサーを利用している場合、エラーではなく単なる文字列として解釈される場合もあります。Playbookを使っていて遭遇するエラーの大半こういった単純な書式のミスの場合が多いので、エディターに書式をチェックしてくれるプラグインを入れると非常に楽になります。コメント以下の例のように行頭に#を付けると行末までがコメント扱いになります。ansible.logエスケープしたい場合には文字列として引用符(ダブルコーテーションなど)で囲うか、バックスラッシュを利用します。\#文字列として扱われるPlaybookの基本的な文法Playbookを書く上での流儀のお話です。パラメーターAnsibleのモジュールにはパラメータが設定できます。ファイルをコピーするcopyモジュールに、コピー元やコピー先のパスを指定するといったものです。プログラミングで言う「引数」、HTMLのタグで言えば「属性」みたいな物ですね。パラメータの書式は主に以下の2種類の書き方ができます。dest=~/foo.txt上記の例ではどちらも同じ意味になります。パラメータは複数指定することが可能ですが、大量に指定する場合には前者を利用した方が可読性が上がります。あとはお好みで使い分ければ良いかと思います。通常、パラメータを記述する順番にとくに指定はありません(=srcとdestが逆になっていても問題ない)。変数Ansible内で変数を利用できます。以下の例では変数filenameを作成し、shellモジュール内で利用しています。}}注意点としてはvarsで変数を定義する際に、別の変数を参照する際には引用符で囲う必要があります。errorとなり停止します。problem.またAnsibleが定義する変数とかぶってしまうため、変数名の冒頭にansible_という文字列はつけないようにします。ループAnsible2.5以降はloop、それよりも古いバージョンではwith_itemsを利用することでループ処理を行うことができます。以下の例では3つのファイルをそれぞれ別のタスクでコピーしています。dest=~/これは次のように書き換えることができます。c.txtloopに配列を指定することで上から順番にモジュールを実行してくれます。}}で値を受け取ることができます。以下のようにハッシュの配列を渡すともう少し複雑なことが可能になります。}ここに上げた例であればwith_itemsでも同様の処理が可能です。loopとwith_itemsはほぼほぼ同じ動作になりますが、階層の深い配列を渡した際の互換性が損なわれています。with_*の項目を参照ください。条件分岐whenを利用することでif文のような条件分岐が可能になります。以下の例では変数DEBUGの値が真(true)のときにのみshellモジュールを実行します。true比較演算子として以下のような物が用意されています。"admin"といった形で条件式を連結できます。root]といった形でOR条件の式を簡潔に記述できます。trueは省略できたのですが、将来的に明示的に記述する仕様に変更になるようで現在では警告メッセージが表示されます。ブロック前述のwhenでは一度にひとつのタスクに対してのみ条件を設定していましたが、blockを利用すれば複数のタスクにまとめて設定することも可能です。truewhenを記述するインデントの階層に注意してください。管理者権限で実行する管理者権限(root権限)で各種処理を実行したい場合は、becomeにyesを指定します。ansible.logもしくは各タスクに個別に付加することも可能です。sudo)で、root以外のユーザーに変更したい場合にはbecome_userを利用します。ansible.log以前はその名の通りsudoというキーワードでしたが、1.9以降からbecomeに変更になりました。ファイルをコピーcopyを使うとPlaybookを実行する側にあるファイルを、管理対象のサーバへコピーできます。用意した設定ファイルを転送したい場合など便利です。apacheこの例では以下のように~/ansible1st/conf/apache/vhost.confにあるファイルを、サーバ側の/etc/httpd/conf.d/vhost.confへコピーしています。★パラメーターや実行例は公式ドキュメントなどを参照ください。既存の設定ファイル等の一部を置換した方が手っ取り早い場合はlineinfileを利用します。shellでsedコマンドなどを利用しても良いのですが、Ansibleのモジュールに用意されている物を利用しておくと、実行する環境が変化したり、コマンドの利用方法が変わった場合も互換性を維持してくれることが期待できます。以下の例ではApacheの設定ファイルhttpd.confのDocumentRootをデフォルトの物から変更しています。"/web/public"'destのファイル内をregexpで検索しlineに置換します。regexpは検索条件に正規表現を利用できます。置換したい場合はwith_itemsやloopを利用するとスッキリと書けます。}パラメーターや実行例は公式ドキュメントを参照ください。パッケージ管理ApacheやMySQLなどミドルウェアのインストールに管理ソフトを利用することが多いと思いますが、Ansibleからももちろん利用できます。インストール/削除/更新その名の通りyumを指定します。nameにインストールしたいパッケージ名、stateにpresentを指定するとインストールされていなければ新規にインストール、インストール済みであれば何もしません。state=present削除したい場合はstateの値をremovedにするだけです。security=yesまたlatestにするとインストールされていなければ新規インストール、すでにインストールされており更新版が存在すればアップデートしてくれます。セキュリティアップデートのみ対応したい場合はさらにsecurity=yesのパラメーターを追加します。一度に複数のパッケージを処理したい場合は複数のタスクを書いても良いのですが、with_itemsやloopを利用するとスッキリします。サーバの起動状態を操作serviceを利用するとApacheやMySQLなどのサーバの起動状態をコントロールできます。起動/再起動/リロード/停止nameに対象のサーバ、stateにstartedを指定すると、サーバが起動していなかった場合に起動します。state=started再起動はstateにrestartedを指定します。state=restartedリロードしたい場合はstateにreloadedを指定します。サーバを起動したままで設定ファイルを読み込み直したいときに使うやつです。state=reloaded同様にサーバを停止する場合にはstateにstoppedを。onを設定することができます。yesその他の情報やパラメーターは公式ドキュメントを参照ください。その他VSCode用プラグインVisualStudioCodeを利用している場合、マイクロソフト謹製のプラグインが用意されています。Marketplacehttps://marketplace.visualstudio.com/items?itemName=vscoss.vscode-ansiblemarketplace.visualstudio.comまたRedhat社から提供されているYAML用の便利プラグインもオススメです。Marketplacehttps://marketplace.visualstudio.com/items?itemName=redhat.vscode-yamlmarketplace.visualstudio.com警告メッセージPythonのパスを指定していない以下の警告が表示されても動作するのですが、気持ちが悪いので潰しておきます。moreinformation.明示的にPythonのパスが設定されていない場合に起こるようなので、Inventory用のファイルにansible_python_interpreterの項目を追加することで表示されなくなります。[servers:vars]ansible_python_interpreter=/usr/bin/python3デフォルトのPython(/usr/bin/python)が2系の場合、3系で動かしたいといった際にもこの指定を行う必要があります。isdebug具体的には以下のメッセージが表示されます。警告なので動きはするのですが気持ち悪いので修正します。ansible.cfg.修正はいたって簡単でwhenに明示的に比較演算子を記述します。trueこれまでは問題なかったのですが今後は厳密になるようですね。続く次回はPlaybookを分割する方法についてです。Playbook分割編https://blog.katsubemakito.net/ansible/ansible-1st-2前回はAnsibleやYAMLの基本的な使い方について書きましたが、今回はPlaybookを分割する方法について取り上げます。自宅警備がてらゲームのお仕事や講師などしてご飯を食べてます。ご質問やリクエストなどお気軽に。メールアドレスの入力は任意です。書き込みが反映されるまで時間がかかります。コメントデータの処理方法の詳細はこちらをご覧ください。ブログをメールで購読メールアドレスを記入して購読すれば、更新をメールで受信できます。