今さらAnsible入門

はじめに

本記事では構成管理ツールであるAnsibleを用いたインフラ構築について説明します。
今さら!?って思われる方もいるかもしれませんが、筆者はその今さらAnsiblerの内の1人(歴3年)なので同じような方をターゲットに今回紹介させてもらいます。

概要編

Ansibleとは

RedHat社が開発/提供する構成管理ツールで、IaC(Infrastructure as Code)に属するもの。
サーバを立ち上げる際、あらかじめ用意した設定ファイルに従って、ソフトウェアのインストールや設定を自動的に実行することができます。
そのため、OSの設定やソフトウェアのインストールを手動で行う必要がなく、また後述する冪等性の特徴からAnsibleで定義したサーバの状態に保つことが可能です。

Ansibleのメリット

構成管理ツールであるAnsibleはChefやPuppetと比較されることが多いので、本記事でも紹介しましょう。


この比較表から分かるように、まずAnsible はエージェントレスで管理対象のサーバにエージェントを導入する必要がない点が大きな利点です。
また、Chef やPuppetのようにプログラミング言語で作成する必要がなく比較的書きやすく読みやすい構造となっています。

冪等性(べきとうせい)について

Ansibleを語る上(Ansibleだけじゃないですが)で、欠かせないのが冪等性です。
冪等性という言葉を調べてみると「同じ操作を何度繰り返しても、同じ結果が得られる概念」と出てきます。
ただ、これではピンとこないですよね。

Ansibleにおける冪等性を簡単に言うと「あるべき姿に保つこと」です。
Ansibleではプレイブック(YAML)というファイルにサーバ等のあるべき姿を記載します。
プレイブックを実行すると対象のサーバがAnsibleで定義した状態に変更します。

図で説明しましょう。

ここではAnsibleのプレイブックにて、「Webサーバにhttpdがインストールされていること」を定義しています。
そのプレイブックを実行すると、Webサーバにhttpdがなければインストール、httpdがあれば何もしないという処理が流れます。
サーバの状態をAnsibleで定義した「あるべき姿」に保っているのです。

Ansible実行環境に必要なもの

Ansibleではプレイブックとインベントリを元にPythonコードを生成します。
そのPythonコードをssh(sftp)でターゲットノードに送り、ターゲットノード側で実行することで設定を行います。

そのため、実行環境に必要なものは以下3つとなります。
  • Ansible
  • SSH(WindowsではWinRM)
  • Python
なお、LinuxであればSSHとPythonはデフォルトで導入されている為、Ansibleだけインストールすれば実行環境を用意することができます。

実習編

概要編で長々と説明してしまいましたが、やってみた方が早い!と思うので実際に触っていきましょう。
AnsibleにはOSS版と商用版がありますが、今回はOSS版を利用します。

構成図

今回作る構成です。
Ansibleの実行環境をAWS上に作成しています。AWS上でしか動かないというような縛りはないです。

構成図の環境が簡単に作れるようCloudFormationテンプレートを用意しています。
ハンズオンを試す際は、こちらのテンプレートを利用してください。

環境構築(CloudFormation)

前提

  • AWSのアカウントを保有してること
  • CloudFormationテンプレートをダウンロードしていること
  • CloudFormationで作成するリソースへの権限を有したIAMユーザで実行すること
    ※筆者はadministrator-access権限を有したIAMユーザを使用しています。

手順

  1. AWSのマネジメントコンソールからCloudFormationにアクセス
  2. CloudFormationの画面にて[スタックの作成]をクリック
  3.  [テンプレートの指定]にて[テンプレートファイルのアップロード]を選択し、[ファイルの選択]からCloudFormationテンプレートをアップロードし[次へ]をクリック


  4. [スタック名]に任意の名前を入力し、[YouGlobalIP]の値に自身のGlobal IP(xxx.xxx.xxx.xxx/32)を入力し[次へ]をクリック

  5. 次の画面では特に何もしていせず[次へ]をクリック


  6. 次の画面では[AWS CloudFormationによってIAM~]のチェックボックスにチェックを入れ、[送信]をクリック


  7. スタックのステータスが"CREATE_COMPLETE"となっていることを確認


  8. AWSのマネジメントコンソールからSystems Managerにアクセス
  9. [パラメータストア]より[マイパラメータ]に作成された"/ec2/keypair.key-xxxxxxxxxxxx"をクリック


  10. [復号化された値を表示]にチェックを入れ、表示された秘密鍵をコピーしてテキストに張り付け。その際、拡張子はpemとすること。


Ansibleハンズオン 事前準備

  1. AWSのマネジメントコンソールにてEC2にアクセス
  2. "ec2-ansible"のパブリックIPをコピーし、ターミナルソフトからSSH接続
    ※その際、秘密鍵にはSystems Managerからコピーした作成したpemファイルを使用してください


  3. ターミナルソフト等を利用してec2-ansible上にSystems Managerからコピーした作成したpemファイルを転送


  4. ec2-ansible上の秘密鍵(pem)をmvしてファイル名変更
    $ mv xxxxx.pem .ssh/id_rsa
  5. 秘密鍵の権限変更
    $ chmod 400 .ssh/id_rsa
  6. ansibleをインストール
    $ /usr/bin/pip3 install ansible

Ansibleハンズオン① WebサーバとDBサーバを作ろう

Ansible実行に必要なファイル

Ansible実行するためには必要最小限のファイルは以下2つになります。
  • インベントリファイル
    •  ターゲットノードのIPアドレス等を定義するファイル
  • プレイブック
    • ターゲットノードのあるべき姿(実行する処理)を定義するファイル

やること

インベントリファイルとプレイブックを作成し、ec2-web001にhttpd、ec2-db001にmariadbをそれぞれインストール、サービス起動を行います。

手順

  1. ansible-handsonディレクトリに移動
    $ cd ~/ansible-handson
  2. web-db.ymlを作成し、以下内容で保存する
    $ vi ~/ansible-handson/web-db.yml [web-db.yml] ==================================================================
    ================================================================== ※枠線の内側の内容を記載してください。 ※説明文を書く都合上、上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。  ★サンプルファイル: web-db.yaml
  3. インベントリファイルを作成し、以下内容で保存する
    ※ansible_host=xxx.xxx.xxx.xxxはそれぞれのEC2インスタンスのプライベートIPアドレスを指定してください
    $ mkdir ~/ansible-handson/inventories
    $ vi ~/ansible-handson/inventories/hosts [hosts]
    ==================================================================

    ================================================================== ※枠線の内側の内容を記載してください。 ※説明文を書く都合上、上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。
     
       ★サンプルファイル: hosts

  4. ansible.cfgを作成、以下内容で保存する
    ※作成必須のファイルではないですが、ハンズオンを円滑に進めるため設定します
    $ vi ~/ansible-handson/ansible.cfg [ansible.cfg] ==================================================================
    ================================================================== ※枠線の内側の内容を記載してください。 ※説明文を書く都合上、上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。 ★サンプルファイル: ansible.cfg
  5. ansible-playbookコマンドを実行する
    $ cd ~/ansible-handson
    $ ansible-playbook -i inventories/hosts web-db.yml [実行結果]

  6. ec2-web001のパブリックIPを用いてブラウザにてhttp://yyy.yyyy.yyy.yyy(パブリックIP)へ接続

PLAY RECAP(要約)について

ansible-playbookコマンドを実行すると最後に必ず実行結果の要約(RECAP)が出力されます。
それぞれの意味は以下の通りになります。

ハンズオン② 冪等性を体感しよう

やること

ec2-web001とec2-db001に対し、ハンズオン⓵で実行したansible-playbookコマンドを再実行しステータスを確認します。
その後、ec2-web001からhttpdをアンインストールし、再度ハンズオン⓵で実行したansible-playbookコマンドを実行しステータスを確認します。
実行ステータスがどのように変わるか見ていきましょう。

手順

  1. ansible-playbookコマンドを実行する
    $ cd ~/ansible-handson
    $ ansible-playbook -i inventories/hosts web-db.yml [実行結果]
  2. ec2-web001にsshログイン
    ※xxx.xxx.xxx.xxxはec2-web001のプライベートIPを指定してください
    $ ssh ec2-user@xxx.xxx.xxx.xxx
  3. httpdをアンインストール
    ※Ansibleで定義した状態から変更します
    $ sudo yum remove -y httpd
  4. ec2-ansibleに戻る(sshログイン)
    ※xxx.xxx.xxx.xxxはec2-ansibleのプライベートIPを指定してください
    ※Ctl + Dでも問題ありません。
    $ ssh ec2-user@xxx.xxx.xxx.xxx
  5. 再度ansible-playbookコマンドを実行する
    $ cd ~/ansible-handson
    $ ansible-playbook -i inventories/hosts web-db.yml

ハンズオン③ WebサーバとDBサーバを作ってみよう(変数)

変数について

Ansibleでは変数を利用して値を入れることができます。
変数値の指定方法はいくつかあるのですが、よく利用されるのはgroup_varsとhost_varsになります。
  • group_vars
    • グループ単位で利用可能な変数
    • group_varsとその配下にグループ名のディレクトリを作成
    • 作成したディレクトリ配下に変数値を記載したYAMLファイルを作成することで参照可能となる
  • host_vars
    • ホスト単位で利用可能な変数
    • host_varsとその配下にホスト名のディレクトリを作成
    • 作成したディレクトリ配下に変数値を記載したYAMLファイルを作成することで参照可能となる

やること

group_varsと変数を利用したプレイブックを作成し、ec2-web002にhttpd、ec2-db002にmariadbをそれぞれインストール、サービス起動を行います。
※host_varsはハンズオン④で触れます。

手順

  1. group_varsディレクトリを作成し、webグループ用の変数ファイルを作成する
    $ cd ~/ansible-handson
    $ mkdir ~/ansible-handson/group_vars
    $ mkdir ~/ansible-handson/group_vars/web
    $ vi ~/ansible-handson/group_vars/web/vars.yml [web/vars.yml] ==================================================================
    ================================================================== ※枠線の内側の内容を記載してください。 ※上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。 ★サンプルファイル: web/vars.yml
  2. dbグループ用の変数ファイルを作成する
    $ mkdir ~/ansible-handson/group_vars/db
    $ vi ~/ansible-handson/group_vars/db/vars.yml [db/vars.yml] ==================================================================

    ================================================================== ※枠線の内側の内容を記載してください。 ※上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。 ★サンプルファイル: db/vars.yml
  3. 変数を利用したweb-db-variable.ymlを作成する
    $ vi ~/ansible-handson/web-db-variable.yml [web-db-variable.yml] ==================================================================
    ==================================================================
    ※枠線の内側の内容を記載してください。 ※説明文を書く都合上、上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。 ★サンプルファイル: web-db-variable.yml
  4. ansible-playbookコマンドを実行する
    $ cd ~/ansible-handson
    $ ansible-playbook -i inventories/hosts web-db-variable.yml [実行結果]

  5. ec2-web002のパブリックIPを用いてブラウザにてhttp://yyy.yyyy.yyy.yyy(パブリックIP)へ接続

ハンズオン④ WebサーバとDBサーバを作ってみよう(Role)

Roleについて

ハンズオン①~③にて作成したプレイブックは1つのファイルにWebサーバ用、DBサーバ用の処理を定義しました。
しかし、これでは必要な処理だけ実行させたい時に困る場合があります。
例えば、Webサーバだけを構築したい場合、ハンズオン⓵~⓷のプレイブックではDBサーバの処理は不要になります。
そのため、Webサーバ用の処理のみを定義したプレイブックを作成する必要がありますが、これでは非効率です。
また、1つのプレイブックにすべての処理を書くと肥大化し可読性も低下します。
その時に使えるのがRoleという機能です。

Roleはプレイブックを疎結合なコンポーネントの処理に分割することで、再利用可能となりプレイブックの可読性を高めることができます。

Roleのディレクトリ構造について

Roleを利用するには決まったディレクトリ構造にする必要があります。
Roleはrolesディレクトリ配下に作成します。例えば、web Roleをroles/webディレクトリの下に定義します。

各Roleの下には、tasks、defualts、vars、templates、handlers等のディレクトリを作成して、Roleの定義を記述することになりますが、この中で必須なのはtasksのみです。

本ハンズオンではtasks以外にtemplates、handlersを利用します。

その他のディレクトリ(defaultsやvars等)の意味については、以下URLを参照ください。

rolesディレクトリ配下のプレイブックの注意点

rolesディレクトリ配下のプレイブックにはhostsやtasksを定義してはならず、
tasks以下の処理のみを記述する必要があります。
ターゲットを示すhostsはRoleを呼び出すプレイブックで指定します。

やること

Webサーバ用、DBサーバ用のRoleを作成し、それぞれの処理を分割します。
web-role.yml、db-role.ymlを作成しそれぞれのRole呼び出し、webグループ、dbグループのサーバに設定を行います。
加えて、Roleには関係ありませんがWebサーバについてはハンズオン③で説明したhost_varsを利用しホスト毎に異なる値を入れて挙動を確認してみましょう。

手順

  1. host_varsディレクトリを作成し、webサーバホスト毎の変数ファイルを作成する
    ※Roleとは関係ありません
    $ cd ~/ansible-handson
    $ mkdir ~/ansible-handson/host_vars
    $ mkdir ~/ansible-handson/host_vars/ec2-web001
    $ vi ~/ansible-handson/host_vars/ec2-web001/vars.yml [ec2-web001/vars.yml] ==================================================================
    ================================================================== ※枠線の内側の内容を記載してください。 ※上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。 ★サンプルファイル: ec2-web001/vars.yml
    $ mkdir ~/ansible-handson/host_vars/ec2-web002
    $ vi ~/ansible-handson/host_vars/ec2-web002/vars.yml [ec2-web002/vars.yml] ==================================================================
    ================================================================== ※枠線の内側の内容を記載してください。 ※上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。 ★サンプルファイル: ec2-web002/vars.yml

  2. rolesディレクトリを作成し、dbロール(tasks/main.yml含)を作成する
    $ mkdir ~/ansible-handson/roles
    $ mkdir -p ~/ansible-handson/roles/db/tasks
    $ vi ~/ansible-handson/roles/db/tasks/main.yml [db/tasks/main.yml] ==================================================================
    ================================================================== ※枠線の内側の内容を記載してください。 ※上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。 ★サンプルファイル: db/tasks/main.yml
  3. dbロール呼び出し用プレイブックを作成する
    $ vi ~/ansible-handson/db-role.yml [db-role.yml] ==================================================================
    ================================================================== ※枠線の内側の内容を記載してください。 ※説明文を書く都合上、上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。 ★サンプルファイル: db-role.yml
  4. ansible-playbookコマンドを実行する
    $ cd ~/ansible-handson
    $ ansible-playbook -i inventories/hosts db-role.yml [実行結果]
  5. webロール(tasks/main.yml含)を作成する
    $ mkdir -p ~/ansible-handson/roles/web/tasks
    $ vi ~/ansible-handson/roles/web/tasks/main.yml [web/tasks/main.yml] ==================================================================
    ================================================================== ※枠線の内側の内容を記載してください。 ※説明文を書く都合上、上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。 ★サンプルファイル: web/tasks/main.yml
  6. webロールにtemplatesディレクトリを作成する
    $ mkdir ~/ansible-handson/roles/web/templates
    $ vi ~/ansible-handson/roles/web/templates/index.html.j2 [web/templates/index.html.j2] ==================================================================
    ================================================================== ※枠線の内側の内容を記載してください。 ※説明文を書く都合上、上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。 ★サンプルファイル: web/templates/index.html.j2
  7. webロールにhandlersディレクトリを作成する
    $ mkdir ~/ansible-handson/roles/web/handlers
    $ vi ~/ansible-handson/roles/web/handlers/main.yml [web/handlers/main.yml] ==================================================================
    ================================================================== ※枠線の内側の内容を記載してください。 ※説明文を書く都合上、上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。 ★サンプルファイル: web/handlers/main.yml
  8. webロール呼び出し用プレイブックを作成する
    $ vi ~/ansible-handson/web-role.yml [web-role.yml] ==================================================================
    ================================================================== ※枠線の内側の内容を記載してください。 ※説明文を書く都合上、上記は画像ファイルとなっています。  コピペで作成したい方は以下サンプルファイルをダウンロードください。 ★サンプルファイル: web-role.yml
  9. ansible-playbookコマンドを実行する
    $ cd ~/ansible-handson
    $ ansible-playbook -i inventories/hosts web-role.yml [実行結果]
  10. ec2-web001とec2-web002のパブリックIPを用いてブラウザにてhttp://yyy.yyyy.yyy.yyy(パブリックIP)へ接続し違いを確認


後片付け(CloudFormation)

手順

  1. AWSのマネジメントコンソールからCloudFormationにアクセス
  2. CloudFormationの画面にて作成したスタック名にチェックを入れ[削除]をクリック
  3. 削除確認が表示されたら[削除]をクリック

  4. しばらく時間をおきCloudFormationの画面から作成したスタックがなくなっていることを確認

さいごに

いかがだったでしょうか。
Ansibleを利用することでサーバへの設定作業が自動的に、簡単に、素早く行えることを体感できたでしょうか。
今回は4台のサーバの簡単な設定を行いましたが、設定内容やサーバの台数が増えるとAnsibleの真価をより感じることができるのではないかと思います。
今回変数やRoleも含めて説明させて頂きましたが、まだまだ紹介できていない内容はあります。
しかしRoleまで理解すればAnsibleできるぜ!と周りに言えることができる実力は備わっていると思います。それを目指して今回説明させてい頂きました。
長々となってしまい読みづらい箇所もあったかと思いますが、少しでもAnsibleの理解度が上がったと思って頂けたなら光栄です。

コメント

このブログの人気の投稿

ProxmoxでLet's Encryptを使用した証明書セットアップをやってみた

AIと共に「考える」エンジニアに!

ルーティングって何で必要で、何してるの?を React Routerで理解する