From 577c57c0cc101d9daf589bf4c1e10a3b55f52a67 Mon Sep 17 00:00:00 2001 From: payalsin Date: Tue, 13 Aug 2019 14:21:13 -0700 Subject: [PATCH 01/37] Update disable-pool-member.yml --- .../ansible_f5/2.0-disable-pool-member/disable-pool-member.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/exercises/ansible_f5/2.0-disable-pool-member/disable-pool-member.yml b/exercises/ansible_f5/2.0-disable-pool-member/disable-pool-member.yml index ed6fdf565..1d65a51e5 100644 --- a/exercises/ansible_f5/2.0-disable-pool-member/disable-pool-member.yml +++ b/exercises/ansible_f5/2.0-disable-pool-member/disable-pool-member.yml @@ -50,6 +50,7 @@ name: "{{item.split(':')[0]}}" pool: "{{pool_name}}" port: "{{item.split(':')[1]}}" + host: "{{hostvars[item.split(':')[0]].ansible_host}}" loop: "{{bigip_facts.ltm_pools | json_query(query_string)}}" vars: query_string: "[?name=='{{pool_name}}'].members[*].name[]" @@ -62,4 +63,5 @@ name: "{{member_name.user_input.split(':')[0]}}" pool: "{{pool_name}}" port: "{{member_name.user_input.split(':')[1]}}" + host: "{{hostvars[member_name.user_input.split(':')[0]].ansible_host}} when: '"all" not in member_name.user_input' From b32dc9a9adaf005dba511e65028659a382373d47 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:27:13 +0900 Subject: [PATCH 02/37] Update README.ja.md --- exercises/ansible_rhel/README.ja.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/exercises/ansible_rhel/README.ja.md b/exercises/ansible_rhel/README.ja.md index 8e02d2c11..ea9ef93df 100644 --- a/exercises/ansible_rhel/README.ja.md +++ b/exercises/ansible_rhel/README.ja.md @@ -31,13 +31,13 @@ Ansibleのベストプラクティスもあわせてご覧ください: ## Section 2 - Ansible Towerの演習 - - [Exercise 2.1 - Towerの紹介](2.1-intro) - - [Exercise 2.2 - インベントリ, クレデンシャル情報, Ad-hoc コマンド](2.2-cred) - - [Exercise 2.3 - Project, job template](2.3-projects) - - [Exercise 2.4 - サーベイ機能](2.4-surveys) - - [Exercise 2.5 - Role based access control](2.5-rbac) - - [Exercise 2.6 - ワークフロー](2.6-workflows) - - [Exercise 2.7 - まとめ](2.7-wrap) + - [演習 2.1 - Tower の紹介](2.1-intro/README.ja.md) + - [演習 2.2 - インベントリー、認証情報、アドホックコマンド](2.2-cred/README.ja.md) + - [演習 2.3 - プロジェクト、ジョブテンプレート](2.3-projects/README.ja.md) + - [演習 2.4 - Survey 機能](2.4-surveys/README.ja.md) + - [演習 2.5 - ロールベースのアクセス制御](2.5-rbac/README.ja.md) + - [演習 2.6 - ワークフロー](2.6-workflows/README.ja.md) + - [演習 2.7 - まとめ](2.7-wrap/README.ja.md) ## 追加情報 From 73fb2da6c7199af52223f33d2c03a20afea4bcf9 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:28:54 +0900 Subject: [PATCH 03/37] Update README.ja.md --- exercises/ansible_rhel/1.1-setup/README.ja.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/exercises/ansible_rhel/1.1-setup/README.ja.md b/exercises/ansible_rhel/1.1-setup/README.ja.md index 05bcae876..9fc45bd0e 100644 --- a/exercises/ansible_rhel/1.1-setup/README.ja.md +++ b/exercises/ansible_rhel/1.1-setup/README.ja.md @@ -1,7 +1,5 @@ # Exercise 1.1 - 要件を確認してみよう -**Read this in other languages**: ![uk](../../../images/uk.png) [English](README.md), ![japan](../../../images/japan.png) [日本語](README.ja.md). - ## ラボ環境について このラボでは、事前設定されたラボ環境で作業します。 以下のホストにアクセスできます。 @@ -18,13 +16,13 @@ SSHでログインできます。: > **Warning** -> +> > **11.22.33.44** のような文字列を、個々に提供されているStudent情報に記載の **IP** などへ読み替えてください。 **X** は student**X** といった具合です. ssh studentX@11.22.33.44 > **Tip** -> +> > パスワードは **ansible** です。 rootになるには以下のように実行してください。: @@ -46,7 +44,7 @@ Ansibleが適切にInstallされているかを確認しましょう。 [...] > **Note** -> +> > Ansibleは構成管理を単純にしてくれます。 Ansibleはデータベースや実行用のデーモンを必要とせず、ラップトップでも簡単に実行できます。 管理対象ホストでは、実行用の常駐エージェントなども不要です。 rootアカウントからログアウトします。 @@ -55,7 +53,7 @@ rootアカウントからログアウトします。 logout > **Note** -> +> > 以降のすべての演習では、明示的な指示がない限り、コントロールノードのstudent\ ユーザーとして作業してください。 ## Step 1.2 - Working the Labs @@ -65,15 +63,15 @@ rootアカウントからログアウトします。 - すべて手で入力するのではなく、必要に応じてブラウザからコピー&ペーストしてください。しかし、考えたり理解したりするのをやめたりしないでください。 - すべてのラボは **Vim** を使って準備しましたが、みんながそれを愛しているわけではないことを理解しています。 **Midnight Commander** などを利用することができます。(**mc**を 実行すると実行できます。ファンクションキーはEsc-\でアクセスするかマウスでクリックすることでアクセスできます。)。または **Nano**(**nano**を実行)なども利用できます。 簡単な[editor intro]も用意してあります。(../ 0.0-support-docs / editor_intro.md) - + ## Step 1.3 - チャレンジLabs -このラボガイドの様々な章で「チャレンジラボ」セクションがあります。 +このラボガイドの様々な章で「チャレンジラボ」セクションがあります。 これらのラボは、これまでに学んだことを使って解決するための様々なタスクを用意しています。 それぞれのラボの解答案は、`Warning`サインより下に記述されています。 ---- -[Click here to return to the Ansible for Red Hat Enterprise Linux Workshop](../README.ja.md#section-1---ansible-engine-exercises) +[Ansible Engine ワークショップ表紙に戻る](../README.ja.md#section-1---ansible-engineの演習) From a8c4f96cc59213c46a265caa06c8641e36b374ff Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:30:10 +0900 Subject: [PATCH 04/37] Update README.ja.md --- exercises/ansible_rhel/1.2-adhoc/README.ja.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/ansible_rhel/1.2-adhoc/README.ja.md b/exercises/ansible_rhel/1.2-adhoc/README.ja.md index 4aaa15af3..5b32a46bf 100644 --- a/exercises/ansible_rhel/1.2-adhoc/README.ja.md +++ b/exercises/ansible_rhel/1.2-adhoc/README.ja.md @@ -275,11 +275,11 @@ node1 | CHANGED => { node1 | CHANGED | rc=0 >> Managed by Ansible ``` -`ansible node1 -m copy …​`コマンドを再実行してみてください。以下の点に着目してみてください: +`ansible node1 -m copy …?`コマンドを再実行してみてください。以下の点に着目してみてください: - 出力結果は、異なる色だったはずです。(適切な端末の設定がされている場合) - `"changed": true,` から `"changed": false,`へ変更されたはずです。 - - 最初の行が、`SUCCESS` から `CHANGED`に変わったはずです。 + - 最初の行が、`CHANGED` から `SUCCESS`に変わったはずです。 > **Tip** > @@ -311,4 +311,4 @@ Managed by Ansible ---- -[Ansible ワークショップ表紙に戻る](../README.ja.md) +[Ansible Engine ワークショップ表紙に戻る](../README.ja.md#section-1---ansible-engineの演習) From edc7e10fa5c539a3de75924b950c04f5883af642 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:31:08 +0900 Subject: [PATCH 05/37] Update README.ja.md --- exercises/ansible_rhel/1.3-playbook/README.ja.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/ansible_rhel/1.3-playbook/README.ja.md b/exercises/ansible_rhel/1.3-playbook/README.ja.md index 77556b3d2..7be9302a8 100644 --- a/exercises/ansible_rhel/1.3-playbook/README.ja.md +++ b/exercises/ansible_rhel/1.3-playbook/README.ja.md @@ -201,7 +201,7 @@ Playbookの次のパートでは、確かにApache Webserverが`node1`上で有 出力された結果をみてみてください。 いくつかのタスクは緑色で"OK"と記載され、1つだけ黄色で"changed"と表示されているはずです。 - - もう一度、AnsibleのAd-Hocコマンドw用いてApacheが有効になっておりかつ起動していることを確認します。例えば、`systemctl status httpd`などを実行しましょう。 + - もう一度、AnsibleのAd-Hocコマンドを用いてApacheが有効になっておりかつ起動していることを確認します。例えば、`systemctl status httpd`などを実行しましょう。 - Playbookをもう一度実行して、出力結果が変わる様に慣れてみましょう。 @@ -325,4 +325,4 @@ Playbookを実行してみましょう: ---- -[Ansible ワークショップ表紙に戻る](../README.ja.md#section-1---ansible-engine-exercises) +[Ansible Engine ワークショップ表紙に戻る](../README.ja.md#section-1---ansible-engineの演習) From 79060fce09ff64691a0ab58af21169b3f73c26c1 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:31:46 +0900 Subject: [PATCH 06/37] Update README.ja.md --- .../ansible_rhel/1.4-variables/README.ja.md | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/exercises/ansible_rhel/1.4-variables/README.ja.md b/exercises/ansible_rhel/1.4-variables/README.ja.md index 98909ea61..939a8f5cd 100644 --- a/exercises/ansible_rhel/1.4-variables/README.ja.md +++ b/exercises/ansible_rhel/1.4-variables/README.ja.md @@ -1,7 +1,5 @@ # 演習1.4 - 変数を使ってみよう -**Read this in other languages**: ![uk](../../../images/uk.png) [English](README.md), ![japan](../../../images/japan.png) [日本語](README.ja.md). - 前回までは Ansible Engine の基礎部分を学習してきました。この演習では Playbook をより柔軟かつパワフルに使用できる、より高度なスキルを学びます。 Ansible では task をよりシンプル、かつ再利用可能にできます。システムの設定にはユニークな設定が含まれる場合があり、 @@ -27,7 +25,7 @@ Playbook では、変数名を二重中括弧で囲むことで変数を表現 > **ヒント** -> +> > ホスト変数には優先順位があります。上記 Host 変数は、 Group 変数より優先されます。詳しくは製品マニュアルをご確認ください。 ## ステップ 1.4.1 - 変数ファイルの作成 @@ -61,7 +59,7 @@ stage: prod - `web` group のすべてのサーバーに対して、変数 `stage` に値 `dev` が定義されます。そして dev (開発)をデフォルト値として定義します。 - - `node2` に関しては、上記で定義された変数 stage = dev が、prod で上書きされます。本番環境として定義されます。 + - `node2` に関しては、上記で定義された変数 stage = dev が、prod で上書きされます。本番環境として定義されます。 ## ステップ 1.4.2 - index.html ファイルの作成 @@ -90,7 +88,7 @@ stage: prod `deploy_index_html.yml` という名前の Playbook を `~/ansible-files/` ディレクトリ内に作成します。 > **ヒント** -> +> > コピーするファイル名の中に指定された変数 "stage" がホストごとに取る値に注意してください。 @@ -118,7 +116,7 @@ stage: prod 各ホストには、変数 stage の値に従って異なるファイルがコピーされているはずです。デフォルトが dev で、node2 のみ、prod となっているはず。それぞれのweb server に curl コマンド(もしくはブラウザ)で接続して確認してみましょう。 ```bash -[student@ansible ansible-files]$ grep node /home/student/lightbulb/lessons/lab_inventory/student-instances.txt +[student@ansible ansible-files]$ grep node ~/lab_inventory/hosts node1 ansible_host=11.22.33.44 node2 ansible_host=22.33.44.55 node3 ansible_host=33.44.55.66 @@ -137,7 +135,7 @@ node3 ansible_host=33.44.55.66 ``` > **ヒント** -> +> > 鋭い人はちょっと思うかもしれません、”もっと柔軟にファイルの中身を変更出来たら・・・、と”。こちらについては次の章(template モジュール)で学びます! ## ステップ 1.4.5 - Ansible ファクト @@ -166,10 +164,10 @@ Ansibleがデフォルトでどのような事実を収集しているのか、 - 管理対象ホストのディストリビューション(Red Hat)を表示してください。ただし、結果は一行で出力してください。 > **ヒント** -> +> > grep を使ってファクトの中から必要な情報を探してみます。次に、 filter を使ってこのファクトのみの情報を抽出してみましょう。一行での表示の方法は ansible コマンドの -h (help) を使って調べてみましょう! - + > **答えは下記の通り\!** ```bash @@ -194,13 +192,13 @@ Ansibleがデフォルトでどのような事実を収集しているのか、 > **ヒント** -> +> > "debug" モジュールは変数や式を確認するのに有用です。 取得されたファクトがどのような形で表示されるか Playbook を実行してみてください。 ```bash -[student@ansible ansible-files]$ ansible-playbook facts.yml +[student@ansible ansible-files]$ ansible-playbook facts.yml PLAY [Output facts within a playbook] ****************************************** @@ -211,13 +209,13 @@ ok: [node1] ok: [ansible] TASK [Prints Ansible facts] **************************************************** -ok: [node1] => +ok: [node1] => msg: The default IPv4 address of node1 is 172.16.190.143 -ok: [node2] => +ok: [node2] => msg: The default IPv4 address of node2 is 172.16.30.170 -ok: [node3] => +ok: [node3] => msg: The default IPv4 address of node3 is 172.16.140.196 -ok: [ansible] => +ok: [ansible] => msg: The default IPv4 address of ansible is 172.16.2.10 PLAY RECAP ********************************************************************* @@ -229,4 +227,4 @@ node3 : ok=2 changed=0 unreachable=0 failed=0 ---- -[Ansible ワークショップ表紙に戻る](../README.ja.md) +[Ansible Engine ワークショップ表紙に戻る](../README.ja.md#section-1---ansible-engineの演習) From 21d3855c4f034d01ddec409e2344520cd2800032 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:32:22 +0900 Subject: [PATCH 07/37] Update README.ja.md --- .../ansible_rhel/1.5-handlers/README.ja.md | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/exercises/ansible_rhel/1.5-handlers/README.ja.md b/exercises/ansible_rhel/1.5-handlers/README.ja.md index d4b98e395..480e10957 100644 --- a/exercises/ansible_rhel/1.5-handlers/README.ja.md +++ b/exercises/ansible_rhel/1.5-handlers/README.ja.md @@ -1,7 +1,5 @@ # 演習 1.5 - 条件分岐, ハンドラー、ループ実行 -**Read this in other languages**: ![uk](../../../images/uk.png) [English](README.md), ![japan](../../../images/japan.png) [日本語](README.ja.md). - ## ステップ 1.5.1 - 条件分岐 Ansible は特定の条件が満たされたときにタスクを実行したり再生したりすることができます。 @@ -26,8 +24,8 @@ Ansible は特定の条件が満たされたときにタスクを実行したり では早速やってみましょう。まず、デフォルトで指定されたインベントリファイル編集し、`ftpserver` グループに `node2` を入れます。 デフォルトのインベントリファイルは、 -`/home/student/lightbulb/lessons/lab_inventory/student-instances.txt` でしたね。♪ - +`~/lab_inventory/hosts` でしたね。♪ + 編集後は以下の様になります。node2 のIPアドレスはご自身ものを入力してください! ```ini @@ -64,7 +62,7 @@ ansible ansible_host=44.55.66.77 ``` > **ヒント** -> +> > 作成完了したら playbook を実行してみてください。やり方は・・・、もう分かってますね (^^♪ 実行した結果を確認してみてください。 `ftpserver` グループに記載された node2 以外のホストはタスクがスキップされ、node2 のみタスクの実行が行われていることが確認できます。 @@ -93,13 +91,13 @@ changed: [node2] まずはコピー元として利用する httpd.conf を node1 から取得します。 > **ヒント** -> +> >このファイルは既に node1 node2 node3 に配置されています。 ```bash [student@ansible ansible-files]$ scp :/etc/httpd/conf/httpd.conf ~/ansible-files/. -student@'s password: +student@'s password: httpd.conf ``` @@ -140,9 +138,9 @@ Listen 8080 ``` - Playbookをもう一度実行してください。興味深い結果が得られます。 - + - httpd.conf が上書きコピーされた - + - ハンドラーが呼び出され、 Apache サービスをリスタートした Apacheはポート8080でリッスンしているはずです。試してみてください。 @@ -158,17 +156,17 @@ curl: (7) Failed connect to :80; Connection refused httpd.conf ファイルを再度 "80" に変更し、どうなるか試してみてください。 > **注意** -> +> > 演習1.7で、ポート8080を使います。この時点で 80ポートをリッスンするよう設定を戻しておいてください。 > **ヒント** -> +> > よく聞かれる質問として、notify セクションが実行されたらすぐにハンドラーが呼び出されるのか?ということがありますが、これは違います。今回の場合、notify 直下にハンドラーが定義されているのですぐの実行となりますが、notiry とハンドラーが離れていた場合は、あくまで上から順に実行され、ハンドラーの順番になったところで実行されます。 notify でハンドラー実行のフラグを立てておく感じです。 ## ステップ 1.5.3 - 単純な繰り返し(ループ実行) -ループを使用すると、同じタスクを繰り返し実行することができます。たとえば、複数のユーザーを作成したいとしましょう。Ansible ループを使用すると、単一のタスクでそれを実行できます。ループは、単なるリスト以外にも反復することができます。たとえば、対応するグループを持つユーザーのリストがある場合、ループはそれらに対しても反復することができます。 詳しくはマニュアルをご確認ください [Ansible Loops](https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html) +ループを使用すると、同じタスクを繰り返し実行することができます。たとえば、複数のユーザーを作成したいとしましょう。Ansible ループを使用すると、単一のタスクでそれを実行できます。ループは、単なるリスト以外にも反復することができます。たとえば、対応するグループを持つユーザーのリストがある場合、ループはそれらに対しても反復することができます。 詳しくはマニュアルをご確認ください [Ansible Loops](https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html) ループの機能を確認してみましょう。 node1 に3人の新しいユーザーを作成します。 `~/ansible-files` ディレクトリの中に、 `loop_users.yml` という名前の playbook を作成します。使用するのは `user` モジュールで、playbook の中身は以下の通りです。 @@ -240,7 +238,7 @@ httpd.conf ファイルを再度 "80" に変更し、どうなるか試してみ - 再度タスクが一覧表示されます。ただし、3つの変更が表示されます。その内容を含む各ループが表示されます。 -node1 内に `prod_user` がグループ `ftp` で作成されていることを確認します。 +node1 内に `dev_user` がグループ `ftp` で作成されていることを確認します。 ```bash [student@ansible ansible-files]$ ansible node1 -m command -a "id dev_user" @@ -250,4 +248,5 @@ uid=1002(dev_user) gid=1002(dev_user) Gruppen=1002(dev_user),50(ftp) ---- -[Ansible ワークショップ表紙に戻る](../README.ja.md) +[Ansible Engine ワークショップ表紙に戻る](../README.ja.md#section-1---ansible-engineの演習) + From 0c37d916868e7071ff7bc60228afed6730f7f867 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:32:51 +0900 Subject: [PATCH 08/37] Update README.ja.md --- exercises/ansible_rhel/1.6-templates/README.ja.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/exercises/ansible_rhel/1.6-templates/README.ja.md b/exercises/ansible_rhel/1.6-templates/README.ja.md index 361b2312b..0e65213d4 100644 --- a/exercises/ansible_rhel/1.6-templates/README.ja.md +++ b/exercises/ansible_rhel/1.6-templates/README.ja.md @@ -1,7 +1,5 @@ # 演習 1.6 - テンプレート -**Read this in other languages**: ![uk](../../../images/uk.png) [English](README.md), ![japan](../../../images/japan.png) [日本語](README.ja.md). - Ansibleは、管理対象ホストにファイルをコピーする際、固定の内容ではなく変数に値を入力しながらコピーを行う様な事も可能です。例えば対象ホストユニークなホスト名などを含んだファイルのコピーを行うことが可能です。これを実現するのが Jinja2 テンプレートです。 Jinja2 は、Python で最も使用されているテンプレートエンジンの1つです。 () ## ステップ 1.6.1 - playbook 内でテンプレートを使用する @@ -57,7 +55,7 @@ Ansibleが変数をシステムから収取したファクト情報で変数を - 「Ansible ファクト」の章で学んだコマンドを使用して、カーネルバージョンを含むファクトを見つけます。 > **ヒント** -> +> > モジュールは `setup` ですね? `grep` 使って探してみましょう。 - 見つかったらその変数を表示するよう、テンプレートファイルに追記しましょう @@ -65,7 +63,7 @@ Ansibleが変数をシステムから収取したファクト情報で変数を - 再度 playbook を実行します - 再度 node1 にログインし、表示をチェックしてみてください - + > **答えは以下の通り** @@ -94,4 +92,5 @@ running kernel {{ ansible_kernel }}. ---- -[Ansible ワークショップ表紙に戻る](../README.ja.md) +[Ansible Engine ワークショップ表紙に戻る](../README.ja.md#section-1---ansible-engineの演習) + From bba8719b6ec7e82a2851362d818fa69b27a591ac Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:33:33 +0900 Subject: [PATCH 09/37] Update README.ja.md --- exercises/ansible_rhel/1.7-role/README.ja.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/exercises/ansible_rhel/1.7-role/README.ja.md b/exercises/ansible_rhel/1.7-role/README.ja.md index 12192d0f1..36a942710 100644 --- a/exercises/ansible_rhel/1.7-role/README.ja.md +++ b/exercises/ansible_rhel/1.7-role/README.ja.md @@ -1,14 +1,12 @@ # 演習 1.7 - Roles: Playbook を再利用可能にする -**Read this in other languages**: ![uk](../../../images/uk.png) [English](README.md), ![japan](../../../images/japan.png) [日本語](README.ja.md). - 今までのワークショップで学習してきた通り、Playbook を1つのファイルに書くことは可能です。しかしそのうち、作成した Playbook を再利用したいと考えるようになると思います。 これを実現するのが Ansible の Roles です。Role という形で Playbook をパーツとして分解し、構造化されたディレクトリに納めるのです。詳しくはこちらの [ベストプラクティス](http://docs.ansible.com/ansible/playbooks_best_practices.html) をご確認ください。 ## ステップ 1.7.1 - Ansible Roles 構造を理解する -Roles は基本的に、ディレクティブを自動化したものであり、実際には参照ファイルの検索パス処理に対するいくつかの機能を超えた追加の魔法的な手段は含まれていません。 +Roles は基本的に、includeディレクティブを自動化したものであり、実際には参照ファイルの検索パス処理に対するいくつかの機能を超えた追加の魔法的な手段は含まれていません。 Roles は定義されたディレクトリ構造に従い、最上位ディレクトリ名で区別されます。いくつかのサブディレクトリの中には `main.yml` という名前の YAML ファイルが含まれています。 `files` と `templates` のサブディレクトリには YAML ファイルによって参照されるオブジェクトを入れておくことができます。 @@ -22,7 +20,7 @@ apache/ ├── handlers │ └── main.yml ├── meta -│ └── main.yml +│ └── main.yml ├── README.md ├── tasks │ └── main.yml @@ -255,7 +253,7 @@ Listen 8080 msg: 'Web server has been configured.' ``` -`pre_tasks` と `post_tasks` というキーワードに注意してください。通常、 Roles のタスクはプレイブックのタスクの前に実行されます。この順番を制御するには、 `pre_tasks` が必要となります。逆に `post_tasks` は、すべての Roles が完了した後に実行されます。ここでは、実際の Roles が実行されたときにどういう順番で実行されたかを確認するため、これら2つのタスクをあえて入れています。 +`pre_tasks` と `post_tasks` というキーワードに注意してください。通常、 Roles のタスクはプレイブックのタスクの前に実行されます。この順番を制御するため、 `pre_tasks` を指定してRolesの前に実行されるタスクを定義できます。逆に `post_tasks` は、すべての Roles が完了した後に実行されます。ここでは、実際の Roles が実行されたときにどういう順番で実行されたかを確認するため、これら2つのタスクをあえて入れています。 Playbook を実行する準備が整いましたので、実行してみましょう! @@ -279,4 +277,4 @@ simple vhost index ---- -[Ansible ワークショップ表紙に戻る](../README.ja.md) +[Ansible Engine ワークショップ表紙に戻る](../README.ja.md#section-1---ansible-engineの演習) From 5a4db4339c57ccf753e5dc54b2f1bc4bc97c9a32 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:34:01 +0900 Subject: [PATCH 10/37] Update README.ja.md --- exercises/ansible_rhel/1.8-bonus/README.ja.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/exercises/ansible_rhel/1.8-bonus/README.ja.md b/exercises/ansible_rhel/1.8-bonus/README.ja.md index 9fdc78df2..f2e20e1b0 100644 --- a/exercises/ansible_rhel/1.8-bonus/README.ja.md +++ b/exercises/ansible_rhel/1.8-bonus/README.ja.md @@ -1,13 +1,11 @@ # 演習 1.8 - ボーナスラボ -**Read this in other languages**: ![uk](../../../images/uk.png) [English](README.md), ![japan](../../../images/japan.png) [日本語](README.ja.md). - あなたは既にラボを完了しています・・・、が、さらに先に進みたい方は是非このボーナスラボにチャレンジしてみてください。 ## ステップ 1.8.1 - ボーナスラボ: アドホックコマンド アドホックコマンドを使って、適当なコメント付きで新しいユーザー "testuser" を `node1` と `node3` に作成します。`node2` に作成してはいけません。実行後、想定通り作成できていることも確認します。 - + - `ansible-doc user` を使ってモジュールのパラメータを確認します。 - アドホックコマンドを使ってコメント "Test D User" 付きのユーザーを作成します。 @@ -17,7 +15,7 @@ - ユーザーを削除し、それが削除されたことを確認します > **ヒント** -> +> > 権限昇格の記述を忘れないこと! > **答えは以下の通り** @@ -40,7 +38,7 @@ `httpd.conf` のリッスンポートを都度 vi 等で編集してコピーするのではなく、変数としてテンプレートの中で定義し、その変数の値を変数ファイルを使って与える方法について考えてみます。 - + - `listen_port` に変数を埋め込んだ `httpd.conf` ファイルを作成し、 `httpd.conf.j2` テンプレートを使って各 node に送付します。 - `web` グループのリッスンポートとして "8080" 、 `node2` のリッスンポートとして `80` を取るように変数ファイルを作成します。 @@ -106,13 +104,13 @@ Playbook `apache_config_tpl.yml` を以下の内容で作成します。 name: httpd state: restarted ``` - + ### 実行し確認します まずは playbook を実行し、curl コマンドで、 `node1` と `node3` にポート `8080` そして `node2` にポート `80` で接続してみます。 ```bash -[student1@ansible ansible-files]$ ansible-playbook apache_config_tpl.yml +[student1@ansible ansible-files]$ ansible-playbook apache_config_tpl.yml [...] [student1@ansible ansible-files]$ curl http://18.195.235.231:8080 @@ -125,5 +123,4 @@ Playbook `apache_config_tpl.yml` を以下の内容で作成します。 ``` ---- - -[Ansible ワークショップ表紙に戻る](../README.ja.md) +[Ansible Engine ワークショップ表紙に戻る](../README.ja.md#section-1---ansible-engineの演習) From 3f250d732af4e902c656ad6848cdf574dc4d70d3 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:36:00 +0900 Subject: [PATCH 11/37] Create README.ja.md --- exercises/ansible_rhel/2.1-intro/README.ja.md | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 exercises/ansible_rhel/2.1-intro/README.ja.md diff --git a/exercises/ansible_rhel/2.1-intro/README.ja.md b/exercises/ansible_rhel/2.1-intro/README.ja.md new file mode 100644 index 000000000..2de4b6b33 --- /dev/null +++ b/exercises/ansible_rhel/2.1-intro/README.ja.md @@ -0,0 +1,75 @@ +# 演習 2.1 - Tower の紹介 + +## Ansible Tower の価値 + +Ansible Towerは、IT自動化のためのエンタープライズソリューションを提供するWebベースのUIです。 + + - ユーザーフレンドリーなダッシュボード形式 + + - Ansibleを補完し、自動化、ビジュアル管理、および監視機能を追加します + + - 管理者にユーザーアクセス制御を提供します + + - 仮想化、クラウドなど様々な情報ソース内のグラフィカルなインベントリの管理と同期が可能です + + - RESTful API に対応しています + + - などなど... + +## Ansible Tower ラボ環境 + +この実習ラボでは、事前設定された実習ラボ環境で作業します。以下のホストにアクセスできます。 + +| Role | Inventory name | +| -----------------------------| ---------------| +| Ansible Control Host & Tower | ansible | +| Managed Host 1 | node1 | +| Managed Host 2 | node2 | +| Managed Host 2 | node3 | + +Ansible Tower はすでにインストールされ、ライセンスが付与されています。WebUI には HTTP / HTTPS 経由でアクセスできます。 + +## ダッシュボード + +Web UI を使用して Ansible Tower に `admin` 権限でログインすると、グラフと以下のような情報が表示されます。 + + - 最近実行したジョブ + + - 管理対象ホストの台数 + + - 問題のあるホストの台数とそのホストへのリンク + +ダッシュボードには、 Playbook で完了したタスクの実行に関するリアルタイムデータも表示されます。 + +![Ansible Tower ダッシュボード](images/dashboard-jp.png) + +## Ansible Tower の概念 + +Ansible Tower を使い始めるには、いくつかの概念と Ansible Tower 独特のオブジェクト名に慣れておく必要があります。 + +**プロジェクト(Projects)** + +プロジェクトは Ansible Tower の Playbook の論理的な集まりです。これらの Playbook は Ansible Tower インスタンス上にあるか、または Tower がサポートするソースコードバージョン管理システム内にあります。 + +**インベントリー(Inventories)** + +インベントリーは、 Ansible Engine のインベントリーファイルと同じように、ジョブを実行する対象ノードの集まりです。インベントリーはグループに分けられ、これらのグループの中に実際のホストが含まれています。インベントリーホストの登録は、1台1台手動で登録することも可能ですし、 Ansible Tower がサポートするクラウドプロバイダや、インベントリースクリプトを使用して自動で登録することも可能です。 + +**認証情報(Credentials)** + +認証情報は、対象ノードに対してジョブを実行したり、インベントリーをダイナミックに同期したり、バージョン管理システムからプロジェクトコンテンツをインポートする時に使用されます。 + +認証情報は保存の際、 Tower によって暗号化されます。このため、登録された後はどのユーザーもコマンドラインでプレーンテキストで取得することはできません。このため、登録されたユーザーの資格情報を公開することなく、他のユーザーおよびチームに、これらの認証情報の使用権限を安全に付与することが可能です。 + + +**テンプレート(Templates)** + +テンプレートにはジョブテンプレートとワークフローテンプレートがあります。ジョブテンプレートは、 Playbook を実行するための定義とパラメータのセットです。ジョブテンプレートは、同じジョブを何度も実行する際に便利です。ジョブテンプレートは、Ansible プレイブックのコンテンツの再利用とチーム間のコラボレーションも促進します。ジョブを実行するには、 Tower では最初にジョブテンプレートを作成する必要があります。ワークフローテンプレートは、複数のジョブテンプレートやワークフローテンプレートをまとめて実行するための機能を提供します。 + +**ジョブ(Jobs)** + +ジョブは基本的に、実行されたジョブテンプレートやワークフローテンプレートのことを指します。 + +---- + +[Ansible Tower ワークショップ表紙に戻る](../README.ja.md#section-2---ansible-towerの演習) From 986803ecdd56fcc3f2f7168753cc5a55aa8e7c97 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:36:37 +0900 Subject: [PATCH 12/37] Add files via upload --- .../2.1-intro/images/dashboard-jp.png | 1112 +++++++++++++++++ 1 file changed, 1112 insertions(+) create mode 100644 exercises/ansible_rhel/2.1-intro/images/dashboard-jp.png diff --git a/exercises/ansible_rhel/2.1-intro/images/dashboard-jp.png b/exercises/ansible_rhel/2.1-intro/images/dashboard-jp.png new file mode 100644 index 000000000..adf210f46 --- /dev/null +++ b/exercises/ansible_rhel/2.1-intro/images/dashboard-jp.png @@ -0,0 +1,1112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + linklight/dashboard-jp.png at devel · hiro52/linklight + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content +
+ + + + + + + + + + +
+ +
+ + +
+ +
+ + + +
+
+
+ + + + + +
+
+
+

Learn Git and GitHub without any code!

+

+ Using the Hello World guide, you’ll start a branch, write comments, and open a pull request. +

+ Read the guide +
+
+
+
+ + + + + + + + +
+
+ +
    + + + + +
  • + +
    + +
    + + + Unwatch + + +
    + Notifications +
    +
    + + + + + + + +
    +
    +
    + +
    +
  • + +
  • +
    +
    + + +
    +
    + + +
    + +
  • + +
  • + + + Fork + + +
  • +
+ +

+ + /linklight + + + + forked from ansible/workshops + +

+ +
+ + + + + + +
+
+
+ + + + + + + + + Permalink + + + + +
+ + +
+ + Branch: + devel + + + + + + + +
+ +
+ + Find file + + + Copy path + +
+
+ + +
+ + Find file + + + Copy path + +
+
+ + + + +
+ Fetching contributors… +
+ +
+ + Cannot retrieve contributors at this time +
+
+ + + + +
+ +
+ +
+ 48.6 KB +
+ +
+ + + + +
+ + + + +
+ +
+
+
+ + + + + + +
+
+ dashboard-jp.png +
+
+ +
+ + + +
+ + +
+ + +
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + +
+ + + You can’t perform that action at this time. +
+ + + + + + + + + + + + + + +
+ + + + From b679d8d4ce344d70827201051b43b3762a8ee7d6 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:39:15 +0900 Subject: [PATCH 13/37] Update README.ja.md --- exercises/ansible_rhel/2.1-intro/README.ja.md | 1 + 1 file changed, 1 insertion(+) diff --git a/exercises/ansible_rhel/2.1-intro/README.ja.md b/exercises/ansible_rhel/2.1-intro/README.ja.md index 2de4b6b33..364b3fb1b 100644 --- a/exercises/ansible_rhel/2.1-intro/README.ja.md +++ b/exercises/ansible_rhel/2.1-intro/README.ja.md @@ -43,6 +43,7 @@ Web UI を使用して Ansible Tower に `admin` 権限でログインすると ![Ansible Tower ダッシュボード](images/dashboard-jp.png) + ## Ansible Tower の概念 Ansible Tower を使い始めるには、いくつかの概念と Ansible Tower 独特のオブジェクト名に慣れておく必要があります。 From 170d339d482948f9c33f5e07e785547c3be3222d Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:42:23 +0900 Subject: [PATCH 14/37] Delete dashboard-jp.png --- .../2.1-intro/images/dashboard-jp.png | 1112 ----------------- 1 file changed, 1112 deletions(-) delete mode 100644 exercises/ansible_rhel/2.1-intro/images/dashboard-jp.png diff --git a/exercises/ansible_rhel/2.1-intro/images/dashboard-jp.png b/exercises/ansible_rhel/2.1-intro/images/dashboard-jp.png deleted file mode 100644 index adf210f46..000000000 --- a/exercises/ansible_rhel/2.1-intro/images/dashboard-jp.png +++ /dev/null @@ -1,1112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - linklight/dashboard-jp.png at devel · hiro52/linklight - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Skip to content -
- - - - - - - - - - -
- -
- - -
- -
- - - -
-
-
- - - - - -
-
-
-

Learn Git and GitHub without any code!

-

- Using the Hello World guide, you’ll start a branch, write comments, and open a pull request. -

- Read the guide -
-
-
-
- - - - - - - - -
-
- -
    - - - - -
  • - -
    - -
    - - - Unwatch - - -
    - Notifications -
    -
    - - - - - - - -
    -
    -
    - -
    -
  • - -
  • -
    -
    - - -
    -
    - - -
    - -
  • - -
  • - - - Fork - - -
  • -
- -

- - /linklight - - - - forked from ansible/workshops - -

- -
- - - - - - -
-
-
- - - - - - - - - Permalink - - - - -
- - -
- - Branch: - devel - - - - - - - -
- -
- - Find file - - - Copy path - -
-
- - -
- - Find file - - - Copy path - -
-
- - - - -
- Fetching contributors… -
- -
- - Cannot retrieve contributors at this time -
-
- - - - -
- -
- -
- 48.6 KB -
- -
- - - - -
- - - - -
- -
-
-
- - - - - - -
-
- dashboard-jp.png -
-
- -
- - - -
- - -
- - -
-
- - - -
- -
- -
-
- - -
- - - - - - -
- - - You can’t perform that action at this time. -
- - - - - - - - - - - - - - -
- - - - From 3651b99772ee9dc325a0706aa3f2aca6d8f0da51 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:42:36 +0900 Subject: [PATCH 15/37] Add files via upload --- .../2.1-intro/images/dashboard-jp.png | Bin 0 -> 49803 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 exercises/ansible_rhel/2.1-intro/images/dashboard-jp.png diff --git a/exercises/ansible_rhel/2.1-intro/images/dashboard-jp.png b/exercises/ansible_rhel/2.1-intro/images/dashboard-jp.png new file mode 100644 index 0000000000000000000000000000000000000000..de9f0d1d0df2744b37e0cd98749e075dca200d21 GIT binary patch literal 49803 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%0AkX&ExgGljtkG*&G}9yI{u7a6ybB z8N9nEw5%{DB$nr8{z@v*_(_q}Mqhj+2gi^Q|80q_W+N`@8#hhqEAFSqWtsYHrBPma z+tM<=V>Gz09An;xcZF1;2fbv;&246>OD3Vlde-MK4x{RMC*J4J(vs~HNx3#5NkM-U zh<(XUgUl^o;3y!IIFQh$2<_A93|ddR{i3>9ES_k$Qks*qB7h`8C&0}jpr4sxqFJbI zI71+Z<9>!6^QWL5NDdB7Rb)xXSmdr$r=>I>Y3!6=-s^t$GiMI!st-evQ-1yC{>;}b zKRTBjnCFcNDe($WRhFAPQ`X959!lA$@8Bbk$u|}saLp!)Fx7)C8H|*S^=rtn$lJt5 zYqgPzn@d*EuFX}5G8}#_sCCS37!EfxpA5-XrqC?Y;VIIpxhKewOqFR)e9Zqn*jf%K z(QA3H9rK`nStpU7lsAIjht^l!UoFkw<-TGM6Bukg1oCSj-7^ZK?n`CWHU&V|7%rd@ zb0L|`3i-aC2b}jNue^Jkekg6hX?nZFiAc(yg-wt`P5F?;6e>0#O1U0=mn+J4(^#*0 zDZ*0U?6Q*n5yOFA08mDTxI|KEvnRO4W6^ykQc}{E=0;>=eII=WA2ALz33T<@6tAfp zu9h?!))!a9X&B9$SOJD9BA{vk07S0}aUgLKymRT9cEQRs!?sj0?ubZB4 zdhahoO^V0tL#6=+`1S`S#=)DjwV4?Arfa{6a5}C+C$cu6m4x-qsYW zt2nW_{+70yu!+lW8Wsc13-5zIu{p#jfsNt4q<8lAqPgZNkx|KgCo$I?{_NF|#>JhS z_W1I*`<_0QPBExc)!A&^if}+mQK5*NX}v4jp=ofR>r=Owxnwr2NKkakxYnb_@c~I0 zThqnzNR#|lt>*r-kdSA4aTrN;=F3NU2w}8hY?~?0wzkh(SJQ~iZhl{{gaZ!ss^D0Z znPYZM~H6AY|CdzP1l+A57ju zlkztAnlTguFs3+JC??XG z-{gzo!=D6=O}xH!Oh@C$1UXI8&ZIVCvgIHFIt5Hr_wec|anFqip-2(3zj$hD=X_Wq zN$-Nj6v{4Vg}C$52TR^upuuroy7m#(l^R9V1BkDe@&LkVzd|>>0Q)dRt_qPQc;DyH z2E$qTuKe8?B_F@M%lY5RpHLr0<9H6zrMy(vZhd-=2cStFtoJ)*sBg>-N?H&Y-~NjS znHxX>iWXq?~M?XSKXAel}p_6QA)bih?UdAa5E`jq9RG#Fy~!GUH{I{ejV z(!sGKoJZr|m%fsfeVt^?`}JujD1IArp%q6jusynh<{`ov2RvTT{?fKUReCM?uneO} zd1jImqMa=KeK%~wrE!iL&t9G*A0*&z8@(-80E|o*V2wVHMr!vt>~viD~RCmI?r!wK9o=aqt4Z7agO7 zAvsmAjy@T=Q%e^N3PC_!DQa((K^pvrXhB53)C%anJ=a#JWJQJd(L6Z+Oh|&+$}LHw zJH0o!atM;3*T5v|89;pL50)1+G%L}2M^Sz5OaRD_CdQL+6FlzOU*?axCj7trD>goP zwflLc5F<)3lLbaTXesEk0IorxYbf!Sl#yX&VR>5rjT&gpX0`!~b1C#smgDxtjwsOJ zoksVY#=&`PS9(GJcR)z>2PJ$dXzIQXh^(Q2=@$$f*7}V=`m4M?BWHvBJQL?w=u4IR z-}sUL_eK2n!s%E3cy7?z%`GLEe zuHIJj#G8krKwrMkruYIE?oTJ(zEfG1zsGIrZ^}T9{OK zDcZ=BjegMZ7oVTh19twYJ+HR+@UWADtCCmogpqI@z+pUv)WFDQdbHn+#@SK5o#ZI7 zYFp1yhRY%LgUo$chvII%yCe&h3leIQA5!^>3~gWLigN{;({CS!t7o`8m;T&ZHu{eb zxeHBQhmkuTK3@o`>=RTudZ;jut*b+7+pd6JMS=#TClZ(lSJ*n{YyyTeJDd^8N|0>v z=R9i^zDY{_*;@}8WMuu^YFpdD4S;Qd=)65dyzvK-+PSEr5az1FPicwSNT)g!tcT>s zw{wBTSxMFi7}hrn!vIOPY$ej7Ib(TBM3cscIa7WLC8DtA94fmA;)mfyP+6c zf9`%;TK(I?0f~+;Ow94W-wORQ1G=`Lqzn=jA&G-VemMyTXqN5TU^bv^-@*nI)mb*Z zot>RP_u^w1s$7rRGP%&|)e8j*LcX!LYY?+)$H&KOYHFfX-F5T=n#WLj_ah3o{SaOX zR1b-6nHyP8uTlu)F)R#TL{laB?6kSN*kNtW0O$+Mz=0qaCB-05V~vicYKkJ6A6?J9 zAZ?E3aUi=~B7X?rNFJ!p%AkFOx~68h2Ns%cz8lc^fq?<*$fAa9JhWbN@Tk7dPXG9n z@0LLs#iN}c0fs2I-;CwuZc}T=0dt19WGVEcc(n$2B?fJtt|0tr6uEps%Kpus)^N#3oX$ak zl2QSAqvT4t+5wmhAx|dIKCDX0Lmcc!wSsM5^DOhTbJy*$)sQ7&bK0c)ps?$;<8h~D=?WstHlMKqlJ)nr1Z3OdxMX)vyYEw zBw;sv;*a-Of=}{mmf@;FjPHIUHpnoZ&Lu2REecP3z?P1fcGwB6W*GXSP)IvyZqlTY ze@5j}<;i@%%H4eIQt~6y1j68Mnkd^*_xl5v(}{MUw)y76+MeR_7JnS+oC@t!5J8gn z<(7V3&Cspeyde=OPcZa!5P8a?9jcO^t(AcW5zSMV*PUL?i}$Ei(~Sx@4)NsyeUGcR z9TlqmJ*4rPjNVfK`L?6Ma@I_~K#bM59&zS%Ma{OUilL1f*X73X`aOx`p=KSL=*8VK z%F@lEMfGMH=^pr-eXsXwrg^_{iZh!aSi}5+V|SYv-2V z!w?;pn(3$C_}e-h4)ZBROxl%l*wBn4lq7KcyV^+!)Oi}Z#c_ghKZ5Q<=^xS{_#wsR z47?8o(gitvwPMm@7+|Ro+a$YLG=huvrjhzgGf=ZRJq9`9WiNmS*SN%%a^fhIaF2pf@CzdWRX658bvnc9GUx><6 z7OU*=e(Dt98m1B!o2?!dDCQ~%FMFdcckIqQ`BF4GMqTyg0S3Q4q+WwfSxBZ$+peH_ z+05(>la{+BpruC1$z(5J9?RqS9knG4O0g`rg+(@4SgG zeEt#$b?3ezBz@o>u(b4qopFb${H+hO8P4(ETmf4&#wbnElA%iU*x8l6y%SuF#Lf~Y zb{Dg3J>@AEPCqk;X=|>Nk%W?waP2BFX1%(?KIV2cZVwg{u!f|44)+#|%G;K=WAqtX zVZkSfJPkR;i!2PdM%_KJQ57`jTsjJLrMldP`G7EVQaY$?7cp5n+KgC4OD;j>%G{R$ zQD~u?{s8VQD=rgj{MWMQuGV_frL+hPPtxge=%=29Ki&e!SiYIrr>IgE(+s&lOkyIh z$^urw^G@0-4RI&9Y7w9d&WVgBS*nZaiwIP*m`=28H9+P1vT!Wy6WmA&%$bgi4q zf&Z;It?)L9VtukSGjoyLvl!5z>6=XLv}eOO180-kUk^Yxc%nGRp6{t3RWukZbxMN(1xptRubXOp~Xsj=2aH8sc#++?T{Edrv%w_b~ zc{bq;EDn-rpW0(-v0l|?bFVr{3Z`jakZH(1K9`j)GZq_(j8D+W)DfUjf7F}fh!qoY zFj0BaIVPD@!8GmFgp}g$Vd%5c3>|tjgNF7?q^AHbr9Xy|mYk;Gu zeUNJ#7*9n>oV!z_WAS+kD(K?wqpfU+!6Q9)sfwuUh=!UE?Ec%l4XklrAvGr-Wvko$ z1KMMWw5sFhI^sh4?LX)p7}Sk1m5wTE8gHt3SqFVIs@r>|?rcfyv86VU2B~g@^L`}1 z6`{jbDOs5sF_nW~P`#i2G{sV4cr~QoH(R@JW$szJZ;Fw~Fvn?P$}rYhv*< zDVp(XFmsa!TJ^iDZt}I{5w-lm(l{$O(dJz>zzq%%-V3E819hz$q6X>?57!!UJ^VYc zZLTNNI>{*Zb(-F$sWq!s)FV;g&=QW&O=$1#%0)I$h;ekUgpm%PkNu3&F4aW;P_Vq{`pM_+=E z|NO>|QM(gIUzy<`y%K!&!fULWDel^4A!ME~-Rkmaeyg0>J694i!sn&w#&+P^2{Lsj zZfRSfyOUI8mKW*p$OE4dUp#A!VbswTPIxcV)`mH`dvc1v?W#;Xtg9m=d*^G=*Ek#Z zjc|%#Ld0X8VXxOQ#FF?du58+d`LqLrJ}d-gkM8El@b4`Nsj$Y4*0~3TU*-Bx=Z}XI z6C=FFSQhhT4KA@bOuBKBoTh9=<{WZjl64u93()1dl|%)Y0}09QDae3s#f8PA!B(rZ zTn+{H6Y15`&YJ@~M&UTlU0MFTHY#C≥}wg85}HQ+d2z8w1Q5yB4leR{DgA4Q)2A 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 XKBk6W-~bq(ghWwZP41(NNzi`*121>C literal 0 HcmV?d00001 From 0eb624cc70a359c5feda7ee73635240d0721da33 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:45:28 +0900 Subject: [PATCH 16/37] Create README.ja.md --- exercises/ansible_rhel/2.2-cred/README.ja.md | 196 +++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 exercises/ansible_rhel/2.2-cred/README.ja.md diff --git a/exercises/ansible_rhel/2.2-cred/README.ja.md b/exercises/ansible_rhel/2.2-cred/README.ja.md new file mode 100644 index 000000000..a615319fc --- /dev/null +++ b/exercises/ansible_rhel/2.2-cred/README.ja.md @@ -0,0 +1,196 @@ +# 演習 2.2 - インベントリー、認証情報、アドホックコマンド + +## インベントリーの作成 + +まず必要なのは、管理対象ホストの一覧です。これは Ansible Engine のインベントリーファイルに相当します。インベントリーにはダイナミックインベントリーなど、高度なものもありますが、まずは基本的なところから始めてみましょう。 + + - ブラウザで **https://student..rhdemo.io** に接続しログインします。 + に関しては環境ごとにユニークな値です。講師の指示に基づき入力してください。 + ユーザーは `admin` パスワードは講師より指示があります。 + +インベントリの作成は以下のように行います。 + + - 左側のWeb UIメニューで、**インベントリー** をクリックし、右端の ![plus](images/green_plus.png) ボタンをクリック。表示されるプルダウンの中から、インベントリーを選択します。 + + - **名前:** Workshop Inventory + + - **組織:** Default + + - **保存** をクリック + +ブラウザ下部に、利用可能なインベントリーが表示されていますので確認してみましょう。 Ansible Tower にあらかじめ作成されている **Demo Inventory** と、今作成した **Workshop Inventory** の2つが存在していることが分かります。ブラウザ上部に戻って、 **Workshop Inventory** の中にある **ホスト** ボタンをクリックすると、まだホストを 1 台も登録していないのでリストが空であることが分かります。 + +早速ホストを追加してみましょう。まず、登録するためのホスト一覧を取得する必要があります。このラボ環境では、Tower がインストールされている ansible Control Host & Tower 上のインベントリーファイルに利用可能なホスト一覧が記述されていますのでそちらを確認してみます。 + +Tower サーバーに SSH でログインします。 + +> **注意** +> +> student\ の \ の部分は、各自与えられた Student 番号を入力ください。また、11.22.33.44の部分は、各自与えられた、ansible Control Hot & Tower の IP アドレスを入力ください。 + +```bash +ssh student@11.22.33.44 +``` + +インベントリーファイルの場所は、Tower ホスト上の、 `~/lab_inventory/hosts` です。 cat で確認してみましょう。 + +```bash +$ cat ~/lab_inventory/hosts +[all:vars] +ansible_user=student +ansible_ssh_pass=ansible +ansible_port=22 + +[web] +node1 ansible_host=22.33.44.55 +node2 ansible_host=33.44.55.66 +node3 ansible_host=44.55.66.77 + +[control] +ansible ansible_host=11.22.33.44 +``` +> **注意** +> +> 表示される IP アドレスは各自固有のものになっていますので、上記とは異なります。 + +node1、node2 などのホストの名前と IP addresses を控えておいてください。これらの情報を以下の手順で Tower のインベントリーに登録していきます。 + + - Tower のインベントリービューで **Workshop Inventory** をクリックします + + - **ホスト** をクリックします + + - ![plus](images/green_plus.png) ボタンをクリックします + + - **ホスト名** `node1` + + - **変数** 3つのハイフン `---` の下(2行目)に、 `ansible_host: 22.33.44.55` を入力します。 IP アドレス、`22.33.44.55` については、先ほど `node1` について確認した IP アドレスに置き換えてください。記述方法についても注意してください。コロン **:** と IP アドレスの間にはスペースが必要です。また、インベントリーファイルで利用するような **=** で記述してはいけません。 + + - **保存** をクリックします + + - **ホスト** に戻って `node2` と `node3` を上記と同様の手順で追加します。 + +これで Tower で管理する 3 台のホストに対するインベントリーファイルの作成が完了です? + +## マシンの認証情報 + +Ansible Tower は、ホストやクラウド等の認証情報をユーザーに開示せずに利用可能にするという優れた機能を持っています。 Tower がインベントリー登録したリモートホスト上でジョブを実行できるようにするには、リモートホストの認証情報を設定する必要があります。 + +> **メモ** +> +> これは Tower が持っている重要な機能の一つ **認証情報の分離の機能です**\! 認証情報はホストやインベントリーの設定とは別で強固に管理することが可能です。 + +Tower の重要な機能なので、まずはコマンドラインでラボ環境について確認してみましょう。 + +SSH 経由で Tower ホストにログインします。 + + - `ssh student@11.22.33.44` いつものように、\ の部分と、Tower ホストのIPアドレスは各自のものに置き換えてください。 + + - `node1` に SSH 接続し、 `sudo -i` を実行してみます。 SSH 接続の際はパスワード入力が要求されますが、 `sudo -i` に関してはパスワードは要求されません。 + +```bash +[student@ansible ~]$ ssh student@22.33.44.55 +student@22.33.44.55's password: +Last login: Thu Jul 4 14:47:04 2019 from 11.22.33.44 +[student@node1 ~]$ sudo -i +[root@node1 ~]# +``` + +これはどういう意味でしょう? + + - **student** は、インベントリーで指定した管理対象ホストにパスワードベースの SSH で接続可能 + + - **student** は、 `sudo` による権限昇格で、**root** としてコマンド実行が可能 + +## マシン認証情報の作成 + +では早速 Tower で認証情報を作成してみましょう。 Tower 左側のメニューから **認証情報** をクリックします。 + + ![plus](images/green_plus.png) ボタンをクリックします。 + + - **名前:** Workshop Credentials + + - **組織:** Default + + - **認証情報タイプ:** 虫眼鏡をクリックして **マシン** を選択し、**選択** をクリックします + + - **ユーザー名:** student\ - いつもの通り、 **\** は各自に割り当てられた番号を入力ください + + - **パスワード:** ansible + + - **保存** をクリックします + + - パスワード部分が暗号化され表示されないことを確認します + +> **ヒント** +> +> Tower では、入力フィールドの横に虫眼鏡アイコンが表示されているときにはクリックすると選択リストが開きます。 + +これで、後でインベントリーホストに使用する資格情報を設定できました。 + +## アドホックコマンドの実行 + +Ansible Engine で実行したアドホックコマンドを Tower でも実行してみましょう。 + + - 左の選択メニューから、**インベントリー** → **Workshop Inventory** + + - **ホスト** ボタンをクリックし、登録したホスト一覧を表示し、`オン` の左にあるチェックボックスを全てのホストでチェックします + + - **コマンドの実行** をクリックします。さらに次の画面でアドホックコマンドを下記の通り指定していきます。 + + - **モジュール** 欄で **ping** を選択 + + - **マシンの認証情報** 欄で **Workshop Credentials** を選択 + + - **起動** をクリックし、出力を確認します + +シンプルな **ping** モジュールにはオプションは必要ありません。しかしながら、他のモジュールの場合、実行には引数が必要な場合があります。次にこのケースを確認してみましょう。先ほどと同様の手順で、今度は **command** モジュールを使って実行中のユーザーのユーザー ID を確認してみます。 + +- **モジュール:** command + +- **引数:** id + +マシンの認証情報も入力して実行の上表示内容を確認します。 + +> **ヒント** +> +> 「引数」の横にある疑問符をクリックすると、モジュールのドキュメントページへのリンクが表示されます。とっても便利ですね。♪ + +次に、/etc/shadow のファイルの中身を確認するコマンドを発行してみましょう + +- **モジュール:** command + +- **引数:** cat /etc/shadow + +> **注意** +> +> **エラーが発生ます** + +失敗します、何故でしょう? + +理由は、そう、権限昇格が必要なのです。もう一度戻って、 **権限昇格の有効化** にチェックを入れて実行してみてください。 + +今回はうまくいきました。 root 権限で実行する必要があるタスクの場合、権限昇格を有効化する必要があります。これは、 Playbook の記述でもよく見かける **become: yes** と同じです。 + +## チャレンジラボ: アドホックコマンド + +アドホックコマンドを使って、node1, node2 node3 にパッケージ「tmux」をインストールしてください。 + +> **ヒント** +> +> **yum** モジュールを利用します。使い方は `[ansible@tower ~]$ ansible-doc yum` などで確認してみてください。 + +> **回答** + + - **モジュール:** yum + + - **引数:** name=tmux + + - **権限昇格の有効化:** チェックします + +> **ヒント** +> +> コマンドの黄色の出力は、Ansibleが実際に何かを実行したことを示しています(ここでは、パッケージがインストールされてなかったのでインストールを実行しました)。アドホックコマンドを再度実行すると、出力が緑色になり、パッケージが既にインストールされていることが通知されます。Ansible の黄色は「注意」を意味するわけではありません…;-)。ご注意を…? ;-). + +---- + +[Ansible Tower ワークショップ表紙に戻る](../README.ja.md#section-2---ansible-towerの演習) From deb4d585cec14f8ead1dd93c3a71cf00d8bb3ee6 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:47:31 +0900 Subject: [PATCH 17/37] Create README.ja.md --- exercises/ansible_rhel/2.3-projects/README.ja.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 exercises/ansible_rhel/2.3-projects/README.ja.md diff --git a/exercises/ansible_rhel/2.3-projects/README.ja.md b/exercises/ansible_rhel/2.3-projects/README.ja.md new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/exercises/ansible_rhel/2.3-projects/README.ja.md @@ -0,0 +1 @@ + From c06a71ae8462698cc3f745b9b27ca72cc70b7216 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:47:48 +0900 Subject: [PATCH 18/37] Create README.ja.md --- exercises/ansible_rhel/2.4-surveys/README.ja.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 exercises/ansible_rhel/2.4-surveys/README.ja.md diff --git a/exercises/ansible_rhel/2.4-surveys/README.ja.md b/exercises/ansible_rhel/2.4-surveys/README.ja.md new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/exercises/ansible_rhel/2.4-surveys/README.ja.md @@ -0,0 +1 @@ + From 40491c3ea2ec822cbf0ea2d435cb2c8fa36c5983 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:48:05 +0900 Subject: [PATCH 19/37] Create README.ja.md --- exercises/ansible_rhel/2.5-rbac/README.ja.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 exercises/ansible_rhel/2.5-rbac/README.ja.md diff --git a/exercises/ansible_rhel/2.5-rbac/README.ja.md b/exercises/ansible_rhel/2.5-rbac/README.ja.md new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/exercises/ansible_rhel/2.5-rbac/README.ja.md @@ -0,0 +1 @@ + From 399b285708aa329f6b3079c931c39c12ec84bb06 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:48:25 +0900 Subject: [PATCH 20/37] Create README.ja.md --- exercises/ansible_rhel/2.6-workflows/README.ja.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 exercises/ansible_rhel/2.6-workflows/README.ja.md diff --git a/exercises/ansible_rhel/2.6-workflows/README.ja.md b/exercises/ansible_rhel/2.6-workflows/README.ja.md new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/exercises/ansible_rhel/2.6-workflows/README.ja.md @@ -0,0 +1 @@ + From 5ab630b85f89ee656bbbd7e71d19dde08793410c Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:48:40 +0900 Subject: [PATCH 21/37] Create README.ja.md --- exercises/ansible_rhel/2.7-wrap/README.ja.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 exercises/ansible_rhel/2.7-wrap/README.ja.md diff --git a/exercises/ansible_rhel/2.7-wrap/README.ja.md b/exercises/ansible_rhel/2.7-wrap/README.ja.md new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/exercises/ansible_rhel/2.7-wrap/README.ja.md @@ -0,0 +1 @@ + From 7ccfe219542a52a44277c84a91bd961655ec5bb7 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:49:06 +0900 Subject: [PATCH 22/37] Update README.ja.md --- .../ansible_rhel/2.3-projects/README.ja.md | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) diff --git a/exercises/ansible_rhel/2.3-projects/README.ja.md b/exercises/ansible_rhel/2.3-projects/README.ja.md index 8b1378917..74e6d55e1 100644 --- a/exercises/ansible_rhel/2.3-projects/README.ja.md +++ b/exercises/ansible_rhel/2.3-projects/README.ja.md @@ -1 +1,188 @@ +# 演習 2.3 - プロジェクトとジョブテンプレート +Tower の **プロジェクト** は、 Git、Subversion、Mercurial、ローカルホルダなど、Playbook の置き場所を定義する仕組みを提供します。 Tower ではサポートとされるソースコード管理(SCM)と連携して Playbook を管理することが可能です。 + +Playbook は SCM など、バージョン管理の仕組みの下に置いておくべきです。このラボでは、 Git リポジトリに保存されている Playbook を利用します。 + +## Git リポジトリのセットアップ +このデモでは、既に Git リポジトリに保存されているプレイブックを使用します。 + +**https://github.com/ansible/workshop-examples** + +このラボで利用する Apache Web Server をインストールするための Playbook は、上記 github サイトの **rhel/apache** に置いてある、`apache_install.yml` です。内容は以下の通りです。 + +```yaml +--- +- name: Apache server installed + hosts: all + + tasks: + - name: latest Apache version installed + yum: + name: httpd + state: latest + + - name: latest firewalld version installed + yum: + name: firewalld + state: latest + + - name: firewalld enabled and running + service: + name: firewalld + enabled: true + state: started + + - name: firewalld permits http service + firewalld: + service: http + permanent: true + state: enabled + immediate: yes + + - name: Apache enabled and running + service: + name: httpd + enabled: true + state: started +``` + +> **ヒント** +> +> Engine の演習で書いた Playbook と比較するとちょっと違っているところがあります。重要なところは、 `become` が無いところと、 `hosts` の設定に `all` を指定しているところです。 + +このリポジトリを Tower の **Source Control Management (SCM)** として利用するには **プロジェクト** を作成する必要があります。 + +## プロジェクトの作成 + + - 左のメニューから **プロジェクト** を選択し、 ![plus](images/green_plus.png) ボタンをクリック。フォームに以下を入力します。 + + - **名前:** Ansible Workshop Examples + + - **組織:** Default + + - **SCM タイプ:** Git + +ここで、リポジトリにアクセスするためのURLが必要です。上記の Github リポジトリに移動し、右側の緑色の **Clone or download** ボタンをクリック。さらに、 **Clone with HTTPS** が選択されていることを確認し、URL をコピーします。 + +SCM URL にコピーした URL を貼り付けます。 + +- **SCM URL:** `https://github.com/ansible/workshop-examples.git` + +- **SCM 更新オプション** 3つのボックスすべてにチェックマークを付けて、常にリポジトリの最新コピーを取得し、ジョブの起動時にリポジトリを更新する設定とします。 + +- **保存** をクリックします + +新しいプロジェクトは、作成後に自動的に同期されます。ただし、これを手動で行うこともできます。 **Projects** ビューに移動し、プロジェクトの右側にある円形矢印 **最新のSCMリビジョンを取得** アイコンをクリックすると、プロジェクトを Git リポジトリと再度同期します。 + +## ジョブテンプレートを作成してジョブを実行する + +ジョブテンプレートは、Ansible ジョブを実行するための定義とパラメーターのセットです。ジョブテンプレートは、同じジョブを何度も実行するのに役立ちます。ジョブテンプレートではいくつかのパラメータを指定します。それぞれの意味は下記の通りです。 + +- **インベントリー:** ジョブを実行するホストを指定します + +- **認証情報:** 管理対象ホストにログインするためのアカウント情報です + +- **プロジェクト:** Playbook の場所を指定します + +- **Playbook の指定** + +早速 **ジョブテンプレート** を作成してみましょう。♪ + +左のメニューから **テンプレート** を選択し、 ![plus](images/green_plus.png) ボタンをクリック。選択肢の中から **ジョブテンプレート** を選びます。 + +> **ヒント** +> +> 下記フィールドの多くは、虫眼鏡アイコンをクリックの上オプション選択で設定が可能です。 + +- **名前:** Apache Install + +- **ジョブタイプ:** 実行 + +- **インベントリー:** Workshop Inventory + +- **プロジェクト:** Ansible Workshop Examples + +- **PLAYBOOK:** `rhel/apache/apache_install.yml` + +- **認証情報:** Workshop Credentials + +- オプションで **権限昇格の有効化** にチェックを入れます + +- **保存** をクリックします + +青い **起動** ボタンを直接クリックするか、テンプレートのビューでロケットアイコンをクリックしてジョブを開始します。ジョブテンプレートを起動すると、自動的にジョブの概要が表示され、Playbook の実行をリアルタイムで追跡できます。 + + +![job exection](images/job_overview.png) + + +完了するまで少し時間がかかりますので、何を行っているか確認してみてください。 + +- インベントリ、プロジェクト、認証情報のチェック、Playbook などのジョブテンプレートの詳細が表示されます + +- さらに、Playbook で変更された部分が記録されています + +- また、開始時刻と終了時刻を含む実行時間も記録されるため、ジョブの実行が実際にどれくらいかかったかがわかります + +- 右側に、プレイブック実行の出力が表示されます。タスクの下のノードをクリックして、各ノードの各タスクの詳細情報が提供されていることを確認します + +ジョブが完了したら、左のメニューからジョブをクリックします。すべてのジョブがここに一覧表示されます。Playbook を実行する前に、SCM 更新が開始されるのが分かります。これは、プロジェクト作成時に、 `起動時のリビジョン更新` にチェックを入れましたね?その Git 情報の更新です! + +## チャレンジラボ: 結果の確認 + +以下に挑戦してみましょう! + + - アドホックコマンドを使用して、対象ホストに Apache がインストールされ、実行されていることを確認します。 + +確認する方法は以前のラボで学んでいると思いますので、考えてやってみてください。 + +> **ヒント** +> +> `systemctl status httpd` を使う!? + +> **回答** + +- **インベントリー** → **Workshop Inventory** + +- **ホスト** をクリックし、対象ホストをチェックにより選択。さらに、 **コマンドの実行** をクリックします。 + +- **モジュール:** command + +- **引数:** systemctl status httpd + +- **マシン認証情報:** Workshop Credentials + +- **起動** をクリック + +## 次のラボの準備も含め少し作業します + +以下を実施ください。 + +> **注意** +> +> 次の章がそれに依存するので、これらの手順を必ず完了してください! + +- `Webserver` という名前のインベントリーを作成し、node1 のみ登録します + +- **テンプレート** をクリックし、 `Install Apache` テンプレートをコピーアイコンを使ってコピーします + +- コピーしたジョブテンプレートを開き `Install Apache Ask` に名前を変更します + +- さらに **インベントリー** で、 `起動プロンプト` にチェックを入れます + +- **保存**します + +- `Install Apache Ask` テンプレートを起動します + +- 使用するインベントリーについて聞かれるので `Webserver` を選択し **次へ** をクリックし、**起動**をクリックします + +- ジョブが終了するのを待ち、 `node1` でしか実行されていないことを確認します。 + +> **ヒント** +> +> Apache は既に最新バージョンでインストールされているため、ジョブは何も変更していないことが分かります。 + +---- + +[Ansible Tower ワークショップ表紙に戻る](../README.ja.md#section-2---ansible-towerの演習) From 2ba9a7a5d7c0b0d0cb95c8a3c917366a652d6266 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:49:38 +0900 Subject: [PATCH 23/37] Update README.ja.md --- .../ansible_rhel/2.4-surveys/README.ja.md | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/exercises/ansible_rhel/2.4-surveys/README.ja.md b/exercises/ansible_rhel/2.4-surveys/README.ja.md index 8b1378917..dac55b391 100644 --- a/exercises/ansible_rhel/2.4-surveys/README.ja.md +++ b/exercises/ansible_rhel/2.4-surveys/README.ja.md @@ -1 +1,137 @@ +# 演習 2.4 - Survey 機能 +テンプレート構成ビューの **SURVEYの追加** ボタンに気付いたかもしれません。Survey は、**テンプレート**が**ジョブ**として起動した時に利用する変数の値を入力する簡単なフォームです。 + +先ほどの演習で、全てのホストに Apache をインストールしました。次にこれを拡張します。 + +- Jinja2テンプレートを持つ適切なロールを使用して、`index.html` ファイルをデプロイします + +- Survey を含むジョブテンプレートを作成し、 `index.html` テンプレート用の情報を収集します + +- ジョブテンプレートを起動します + +さらに、このロールでは、他の演習で失敗していることも想定し、Apache 構成が適切にセットアップされていることも確認します。 + +> **ヒント** +> +> Survey は入力するデータの単純なクエリのみを提供します。動的なデータに基づくクエリやネストされたメニューには対応していません。 + +## プロジェクトを作成する + +Playbook と Jinja2 テンプレートを持つ Roles は Github リポジトリ + +**https://github.com/ansible/workshop-examples** の `rhel/apache` にあります。 + +Github UIに移動して、 `apache_role_install.yml` の中身を見てみてください。単に Role を参照しているだけです。 Role は `roles/role_apache` サブディレクトリに存在します。Role 内の jinja2 テンプレート `templates/index.html.j2` 内に定義された二つの変数を確認します。変数は `{{…?}}` で定義されるんでしたね。また、メインのタスクを担う、 `tasks/main.yml` の中で、template からファイルをコピーするタスクをチェックします。この Playbook は何をやっているのでしょう、分かりますか? テンプレート (**src**) から、対象ホスト上にファイル (**dest**) としてコピーしています。この際、コピー先のファイルには変数に値が入力されます。値を入力するのは、そう、 Survey インターフェースです。 + +Role は、Apache の設定内容もデプロイします。前の章で行われた全ての変更が上書きされ、今回の演習が問題なく実行できることを保証するためのものです。 + +## Survey を作成 + +Survey を含むジョブテンプレートを作成します。 + +### テンプレートの作成 + +- 左のメニューで**テンプレート**を選択し、![plus](images/green_plus.png) ボタンをクリック。 **ジョブテンプレート**を選択します。 + +- **名前** Create index.html + +- テンプレートを次のように構成してください! + + - 既存の**プロジェクト** の中から今回の件に適応するものを選択。さらに適切な **Playbook**を選びます。 + + - `node1` のみで実行されるようにインベントリーを定義します + + - 権限昇格を行います + +設定方法は分かりますか?答えは以下の通りです。ここまで演習を積まれた皆さんならそんなに難しくないと思います。♪ + +> **回答** + +- **名前:** Create index.html + +- **ジョブタイプ:** 実行 + +- **インベントリー:** Webserver + +- **プロジェクト:** Ansible Workshop Examples + +- **PLAYBOOK:** `rhel/apache/apache_role_install.yml` + +- **認証情報:** Workshop Credentials + +- **オプション:** 権限昇格の有効化 + +- **保存**をクリック + +> **注意** +> +> **まだジョブテンプレートを実行しないでください!! そう、まだ変数の値が定義されてません!!** + +### Survey を追加する + +- ジョブテンプレートの中で、**SURVEY の追加** ボタンをクリックします + +- **Survey プロンプトの追加** フォームで以下を入力します + + - **プロンプト:** First Line + + - **回答の変数名:** `first_line` + + - **回答タイプ:** テキスト + +- **+ADD**をクリックします。 + +- 同じように2つ目の変数入力フォームを定義します + + - **プロンプト:** Second Line + + - **回答の変数名:** `second_line` + + - **回答タイプ:** テキスト + +- **+ADD**をクリックします + +- **保存** をクリックし、 Survey を保存します + +- **保存** をクリックし、ジョブテンプレートを保存します + +## テンプレートを起動します + +作成したジョブテンプレート **Create index.html** を起動してみます。 + +実際の起動の際に、Survey は 2つの変数について入力を要求します。お好きなテキストを入力して、「次へ」をクリックします。次のウィンドウに入力した値が表示されます。問題なければ、「起動」をクリックしてジョブを実行します。 + +> **ヒント** +> +> 入力した 2つの値がジョブ実行画面の左下の **追加変数**に表示されていることを確認します。 + +ジョブが完了したら、Apache ホームページを確認してください。確認するのは、そう、`node1` です。 Tower Server の SSH コンソールの curl コマンドで確認したもよいですし、ブラウザで直接 node1 に接続してみてもOKです。 + +```bash +$ curl http:// + +

Apache is running fine

+

This is survey field "First Line": line one

+

This is survey field "Second Line": line two

+ +``` +この index.html ファイルが Playbook と Survey によってどのように作成されたのか、よく理解しておて下さい。 + +## さらに次のタスクを実行ください + +タスクのリストは次のとおりです。 + +> **注意** +> +> **次の章で利用しますので、以下の手順は必ず完了してください!** + +- インベントリー `Webserver` に、 `node2` と `node3` を追加します + +- ジョブテンプレート `Create index.html` を再度実行します。 + +- Curl コマンドもしくはブラウザで `node2`, `node3` にアクセスし、結果を確認します。 + +---- + +[Ansible Tower ワークショップ表紙に戻る](../README.ja.md#section-2---ansible-towerの演習) From f70e56289d15097c999739da5e2517b430af9657 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:50:17 +0900 Subject: [PATCH 24/37] Update README.ja.md --- exercises/ansible_rhel/2.5-rbac/README.ja.md | 108 +++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/exercises/ansible_rhel/2.5-rbac/README.ja.md b/exercises/ansible_rhel/2.5-rbac/README.ja.md index 8b1378917..fba56b583 100644 --- a/exercises/ansible_rhel/2.5-rbac/README.ja.md +++ b/exercises/ansible_rhel/2.5-rbac/README.ja.md @@ -1 +1,109 @@ +# 演習 2.5 - ロールベースのアクセス制御 +Ansible Tower の優れた機能として、認証情報を Tower 内部で適切に管理する方法を学びました。Ansible Tower のもう1つの利点は、ユーザーとグループの権限管理です。 + +## Ansible Tower ユーザー + +Ansible Tower のユーザーには以下の3つのタイプがあります + +- **Normal User** インベントリやプロジェクトなどのオブジェクトに対する読み込み、書き込み権限は、そのユーザーに与えらたロールや権限に限定される + +- **System Auditor** Ansible Tower 環境内のすべてのオブジェクトの読み取り専用権限を有します + +- **System Administrator** Ansible Tower 環境内のすべてのオブジェクトに対して読み取り、書き込みの権限があります + +早速ユーザーを作成しましょう + +- 左のメニュー一覧から **ユーザー**をクリックします + +- 緑色のプラスボタンをクリックします + +- 新しいユーザーに関する情報を入力します + + - **名** Werner + + - **姓** Web + + - **メール** wweb@example.com + + - **ユーザー名** wweb + + - **ユーザータイプ** Normal User + + - **パスワード** ansible + +- **保存**をクリック + +## Ansible Tower チーム + +チームは、ユーザー、プロジェクト、資格情報、および権限が関連付けられた組織の下位に当たる区分けです。チームは、ロールベースのアクセス制御スキームを実装し、組織全体に責任を委任する手段を提供します。たとえば、チームの各ユーザーではなく、チーム全体に権限が付与される場合があります。 + +チームを作成します + +- 左のメニューで**チーム**をクリック + +- 緑色のプラスボタンをクリックして、 `Web Content` という名前のチームを作成します + +- **保存**をクリックします + +これでユーザーをチームに登録することができます。 + +- チーム `Web Content` 内の **ユーザー** ボタンをクリックします + +- 緑色のプラスボタンをクリックし、wweb ユーザーの横にあるチェックボックスをオンにして、**保存**をクリックします。 + +今度は、**パーミッション** ボタンをクリックしてみてください。 "パーミッションが付与されていません"と表示されていると思います。 + +権限を付与することにより、プロジェクト、インベントリ、およびその他の Ansible Tower 内のオブジェクトの読み取り、変更、および管理が可能になります。この権限は、Ansible Tower で管理するさまざまなリソースに設定できます。このあたりの柔軟性が Tower のもう一つの大きな特徴です。 + +## パーミッションの付与 + +ユーザーまたはチームが Ansible Tower 上で作業する場合、作業に対する適切なアクセス権限を持っている必要があります。新規に作成したユーザー wweb に対し、割り当てられた Web サーバーのコンテンツの変更(具体的には Create index.html ジョブテンプレートの実行権限)のみを許可してみましょう。 + +テンプレートを使用する権限を追加します。 + +- チーム `Web Content` 内で `パーミッション` を表示し、緑色のプラスボタンをクリックして権限を追加します。 + +- 新しいウィンドウが開きます。様々なオブジェクトに対してアクセス権限を設定できることが分かります。 + + - **ジョブテンプレート**を選択します + + - `Create index.html` テンプレートの横にあるチェックボックスをオンにしてテンプレートを選択します。 + +- ウィンドウの2番目の部分が開きます。ここで、選択したリソースにロールを割り当てます。 + + - **実行**を選択します + +- **保存**をクリックします + +## パーミッションのテスト + +Ansible Tower の Web UI からログアウトし、**wweb**ユーザーとして再度ログインします。 + +- **Templates** ビューに移動します。wweb の場合は、Create index.html テンプレートのみが表示されます。彼は、このテンプレートを閲覧したり、実行したりすることは許可されています。 + +- ロケットのアイコンをクリックして、ジョブテンプレートを実行します。アンケートの内容を好みに合わせて入力し、ジョブを開始します。 + +- ジョブの実行結果を確認ください。変更された内容があることが分かります。変数値ですね、もちろん。 + +結果を `node1` に対する curl コマンドで確認します。   + +```bash +$ curl http://22.33.44.55 +``` + +ここで実施した内容について理解できましたか?制限されたユーザーが権限を与えられることにより Ansible Playbook を実行できるようにしました。しかもこのユーザーは必要以上の権限は与えられていません。 + + - 資格情報にアクセスできない + + - Playbook 自体を変更できない + + - しかし、事前に定義された変数を定義する権限を有しています! + +この様に、Ansible Tower では、認証情報を必要以上に提供したり、ユーザーに Playbook を変更したりする権限を与えることなく、柔軟に自動化を実行する権限のみを提供することができます。 + +この機能は、Ansible Towerの主な強みの1つです! + +---- + +[Ansible Tower ワークショップ表紙に戻る](../README.ja.md#section-2---ansible-towerの演習) From 59436ca00ebf8455058169e338526b30f8ddede9 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:50:41 +0900 Subject: [PATCH 25/37] Update README.ja.md --- .../ansible_rhel/2.6-workflows/README.ja.md | 198 ++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/exercises/ansible_rhel/2.6-workflows/README.ja.md b/exercises/ansible_rhel/2.6-workflows/README.ja.md index 8b1378917..554ee3b70 100644 --- a/exercises/ansible_rhel/2.6-workflows/README.ja.md +++ b/exercises/ansible_rhel/2.6-workflows/README.ja.md @@ -1 +1,199 @@ +# 演習 2.6 - ワークフロー +# Ansible Tower ワークフロー + +Ansible Tower の主要な新機能としてバージョン 3.1 からワークフローが導入されました。ワークフローの基本的な考え方は、複数のジョブテンプレートをリンクし実行できることです。各ジョブテンプレートの実行は、例えば以下の様な実行条件を付与することができます。 + + - ジョブテンプレート A が成功すると、ジョブテンプレート B が自動的に実行される + + - ただし、失敗した場合は、ジョブテンプレート C が実行される + +また、ワークフローはジョブテンプレートだけではなくプロジェクトやインベントリの更新を行うこともできます。 + +このラボでは、ワークフローの設定方法を学びます。 + +## ラボシナリオ + +組織には以下の2つの部門があります。 + + - 自分の Git リポジトリで Playbook を開発・利用して Web アプリケーションを運用しているチーム + + - Git リポジトリで Tomcat 用の JSP Web アプリケーションを開発しているチーム + +新しい Tomcat サーバーをデプロイする必要がある場合、以下の 2 つのことを行う必要があります + + - Tomcat をインストールし、ファイアウォール設定を行い、Tomcatサービスを開始する + + - Web アプリケーション開発チームが作成した最新の Web アプリケーションを展開する + +Playbook、JSP ファイルなど、必要なものはすべて Git リポジトリーに存在します。それを利用してラボを行います。 + +> **メモ** +> +> シナリオでは、2 つの異なる Git リポジトリの利用を想定していますが、このラボでは同じリポジトリの2つの異なるブランチにアクセスしています + +## プロジェクトの設定 + +先のラボで実施した通り、まずはプロジェクトを作成し、 Git リポジトリを登録する必要があります。必要な情報は以下です。ご自身で設定してみてください。 + +> **注意** +> +> このラボは admin アカウントで実施ます。 **wweb** ユーザーでログインしている場合は、ログアウトして **admin** でログインしなおしてください! + +- web オペレーションのためのプロジェクトを作成します + + - 名前は **Webops Git Repo** とします + + - SCM アクセス先は **https://github.com/ansible/workshop-examples.git** です + + - **SCM BRANCH/TAG/COMMIT** は **webops** とします + +- アプリケーション開発者向けのプロジェクトを作成します。 + + - 名前は **Webdev Git Repo** とします + + - SCM アクセス先は **https://github.com/ansible/workshop-examples.git** です + + - **SCM BRANCH/TAG/COMMIT** は **webdev** とします + + +> **回答は以下の通り** + +- Web 運用者用のプロジェクトを作成します。**プロジェクト**画面より緑色のプラスボタンをクリックし、以下の値を入力します。 + + - **名前** Webops Git Repo + + - **組織** Default + + - **SCM タイプ** Git + + - **SCM URL:** https://github.com/ansible/workshop-examples.git + + - **SCM BRANCH/TAG/COMMIT** webops + + - **SCM 更新オプション** 全てにチェックします + +- **保存**をクリックします + +- Web アプリ開発者用のプロジェクトを作成します。**プロジェクト**画面より緑色のプラスボタンをクリックし、以下の値を入力します。 + + - **名前** Webdev Git Repo + + - **組織** Default + + - **SCM タイプ** Git + + - **SCM URL** https://github.com/ansible/workshop-examples.git + + - **SCM BRANCH/TAG/COMMIT** webdev + + - **SCM 更新オプション** 全てにチェックします + +- **保存**をクリックします + +## ジョブテンプレートの作成 + +最終目標はワークフローの作成ですが、まず、通常のジョブテンプレートを作成する必要があります。 + + - **テンプレート** を選択し、色のプラスボタンをクリックして、**Job Template**を選択します + + - **名前** Tomcat Deploy + + - **ジョブタイプ** 実行 + + - **インベントリー** Workshop Inventory + + - **プロジェクト** Webops Git Repo + + - **PLAYBOOK** `rhel/webops/tomcat.yml` + + - **認証情報** Workshop Credentials + + - **オプション** 権限昇格の有効化にチェックを入れます + + - **保存**をクリック + + - 上記の内容をアプリチームに対して繰り返します。**テンプレート** を選択し、色のプラスボタンをクリックして、**ジョブテンプレート**を選択します + + - **名前** Web App Deploy + + - **ジョブタイプ** 実行 + + - **インベントリー** Workshop Inventory + + - **プロジェクト** Webdev Git Repo + + - **PLAYBOOK:** `rhel/webdev/create_jsp.yml` + + - **認証情報** Workshop Credentials + + - **オプション** 権限昇格の有効化にチェックを入れます + + - **保存**をクリック + +> **ヒント** +> +> Playbook の中身をご覧になりたい方は、 Github URL を確認して、適切なブランチに切り替えてご覧ください。 + +## ワークフローの設定 + +ジョブテンプレートが出来上がりましたので、ワークフローテンプレートを作成してみましょう? +ワークフローテンプレートも左メニューの**テンプレート**より作成します。 + + - **テンプレート** を選択し、色のプラスボタンをクリックして、**ワークフローテンプレート**を選択します。 + + - **名前** Deploy Webapp Server + + - **組織** Default + + - **保存** + + - これで**ワークフロービジュアライザー**ボタンがアクティブになります。早速クリックしてグラフィカルエディターを起動します。 + + - **開始** ボタンをクリックすると、Node 画面が開きます。右側で、ノードにアクションを割り当てることができます。**ジョブ**、**プロジェクトの同期**、**インベントリー同期**のいずれかが選択できます。 + + - この実習ラボでは、先に作成したジョブテンプレートをリンクします。そのため、**Tomcat Deploy** ジョブを選んで**選択**をクリックします。 + + - 左側にノードが現れます。ノードにはジョブの名前が入っています。ノードの上にマウスポインターを合わせると、赤い**x**と緑の**+** 記号、真ん中には鎖のような青い記号が表示されます。 +> **ヒント** +> +> 赤い「x」を使用するとノードを削除でき、緑のプラスを使用すると次のノードを追加できます。青は他のノードへのリンク作成を行う際に使います。 + + - 緑の**+** を選択します + + - 次のジョブとして Web App Deploy を選択します(次のページに切り替える必要がある場合があります) + + - **実行** は**成功時**のままにします。 + +> **ヒント** +> +> この実行を使うことにより、より複雑なワークフローが可能になります。Playbook の実行が成功した場合と失敗した場合に、異なる実行パスをレイアウトできます。 + + - **選択** をクリック + + - **ワークフロービジュアライザー**画面で保存をクリックします + + - **ワークフローテンプレート**画面で保存をクリックします + +## 実行してみましょう + +作成が完了しましたので早速動作させてみましょう♪ + + - **起動** ボタンを直接クリックしても良いですし、**テンプレート画面**でロケットアイコンをクリックしても起動ができます。 + +![jobs view of workflow](images/job_workflow.png) + +ジョブビューでワークフローの実行がどのように表示されるかに注意してください。今回の通常のジョブテンプレートジョブの実行とは対照的に、右側にはプレイブックの出力はありませんが、複数のジョブステップの実行状況が表示されます。各ジョブで実行されたプレイブックの状況を確認したい場合は、各ステップの**詳細**をクリックしてください。再度ワークフロー実行画面に戻りたい場合は、左の画面の Web App Deloy の右隣にある小さな ![w-button](images/w_button.png) をクリックしてください。 + +ジョブが完了した後、すべてがうまく働いたかどうかを確認node1、node2またはnode3お使いの制御ホストから以下を実行します。 + +```bash +$ curl http://localhost:8080/coolapp/ +``` + +> **ヒント** +> +> Tomcat がリクエストに応答するまで、数分待たなければならない場合があります。 + +---- +[Ansible Tower ワークショップ表紙に戻る](../README.ja.md#section-2---ansible-towerの演習) From 4725f5844c6a017a4afba9e19f272f607bb4c4f8 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:51:07 +0900 Subject: [PATCH 26/37] Update README.ja.md --- exercises/ansible_rhel/2.7-wrap/README.ja.md | 167 +++++++++++++++++++ 1 file changed, 167 insertions(+) diff --git a/exercises/ansible_rhel/2.7-wrap/README.ja.md b/exercises/ansible_rhel/2.7-wrap/README.ja.md index 8b1378917..49c10ebd1 100644 --- a/exercises/ansible_rhel/2.7-wrap/README.ja.md +++ b/exercises/ansible_rhel/2.7-wrap/README.ja.md @@ -1 +1,168 @@ +# 演習 2.7 - まとめ +# 最終チャレンジとまとめ + +今までに学んだことを踏まえて以下の課題を実施してみましょう。 + +## ステージの設定 + +今までの演習の延長です。以下の演習にチャレンジしてみましょう。 + +- すべてのWebサーバー(`node1`、`node2`および `node3`)は1つのグループに入れる必要があります + +- Webサーバーは開発目的または本番稼働で使用するため、 "stage dev" または "stage prod" としてそれに応じてフラグを立てる必要があります + + - 現在 `node1` `node3` は開発用として利用されており、 `node2` は本番環境として稼働しています + +- もちろん、世界的に有名な?アプリケーション "index.html" は開発と本番で内容が異なります + + - ページに環境を説明するタイトルが必要です + + - コンテンツ用の場所を作りましょう + +- Web コンテンツの開発者 `wweb` 開発及び本番ホストのコンテンツ変更のため、Survey 入力を行うための権限が必要です + +## Git リポジトリ + +すべてのコードは Github にあるものを使います。https://github.com/ansible/workshop-examples で **Ansible Workshop Examples** の gitリポジトリを確認してください。そこに `role_webcontent Role` を呼び出すプレイブック `webcontent.yml` があります。 + +以前の Apache インストールロールと比較すると、大きな違いがあります。`index.html` テンプレートには2つのバージョンがあり、そのソースファイルの一部には変数入力が存在し、タスクによりこのテンプレートがデプロイされます。 + +`dev_index.html.j2` + +```html + +

This is a development webserver, have fun!

+{{ dev_content }} + +``` + +`prod_index.html.j2` + +```html + +

This is a production webserver, take care!

+{{ prod_content }} + +``` + +`main.yml` + +```yaml +[...] +- name: Deploy index.html from template + template: + src: "{{ stage }}_index.html.j2" + dest: /var/www/html/index.html + notify: apache-restart +``` + +## インベントリーを確認する + +これを達成する方法は1つだけではありませんが、次のことを行う必要があります。 + +- すべてのホストがインベントリグループ `Webserver` に含まれていることを確認します + +- `Webserver` インベントリーで、変数 `stage` を `dev` で定義 + + - `Webserver` インベントリー の**変数**欄で、2行目に `stage: dev` を入力します + +- 同じ要領で、今度は、`node2` に対して変数 `stage: prod` を指定しますが、今回は `node2` をクリックしてホストインベントリー変数として上書きします。 + +> **ヒント** +> +> YAML スタートを意味する1行目のハイフンは消さないでください! + +## テンプレートの作成 + +- 新しい **ジョブテンプレート** を `Create Web Content` という名前で作成します + + - ターゲットは `Webserver` インベントリーです + + - Playbook は、**Ansible Workshop Examples** の `rhel/apache/webcontent.yml` を使います + + - 2 つの変数の値を、 `dev_content: default dev content` と `prod_content: default prod content` として、**追加変数**欄に入力します。 + + - 認証情報は `Workshop Credentials` を使い、権限昇格の上実行します + +- テンプレートを保存します + +## 結果を確認します + +今回は、Ansibleのアドホックコマンドを使って結果を確認します。利用するモジュールは command モジュールで、各ノードの curl 実行結果を確認してみます。 + +```bash +$ ansible web -m command -a "curl -s http://localhost:80" + [WARNING]: Consider using the get_url or uri module rather than running 'curl'. If you need to use command because get_url or uri is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. + +node2 | CHANGED | rc=0 >> + +

This is a production webserver, take care!

+prod wweb + + +node1 | CHANGED | rc=0 >> + +

This is a development webserver, have fun!

+dev wweb + + +node3 | CHANGED | rc=0 >> + +

This is a development webserver, have fun!

+dev wweb + +``` + +Ansible では、 `curl` コマンドを `command` モジュールで実行するよりも優れたモジュールが提供されているため、警告が出ますが、今回は無視して大丈夫です。 + +## Survey の追加 + +- 変数 `dev_content` と `prod_content` の内容を変更できるように、Surveyを追加します + +- `Web Content` チーム内の `wweb` ユーザーが、 **Create Web Content** を実行できるように権限を追加します + +- `wweb` ユーザーで Survey 入力を行います + +結果を確認しまし。先ほど `command` モジュールで `curl` を実行し、警告が表示されたので、今回は専用 `uri` モジュールを使用します。引数として、実際の URL と結果の本文を出力するフラグが必要です。 + +```bash +$ ansible web -m uri -a "url=http://localhost return_content=yes" +node2 | SUCCESS => { + "accept_ranges": "bytes", + "ansible_facts": { + "discovered_interpreter_python": "/usr/bin/python" + }, + "changed": false, + "connection": "close", + "content": "\n

This is a production webserver, take care!

\nprod wweb\n\n", + "content_length": "77", + "content_type": "text/html; charset=UTF-8", + "cookies": {}, + "cookies_string": "", + "date": "Wed, 10 Jul 2019 22:15:45 GMT", + "elapsed": 0, + "etag": "\"4d-58d5aef2a5666\"", + "last_modified": "Wed, 10 Jul 2019 22:09:42 GMT", + "msg": "OK (77 bytes)", + "redirected": false, + "server": "Apache/2.4.6 (Red Hat Enterprise Linux)", + "status": 200, + "url": "http://localhost" +} +[...] +``` + +## 解決方法 + +> 解決方法はここでは記載しません + +ラボで必要な構成手順はすべて完了しています。不明な場合は、それぞれの章を参照してください。 + +# 終わり + +おめでとうございます、ラボを終了しました! 我々はこのラボを楽しく開発しました。皆様の Ansible Tower との初めて出会いが、それ以上に楽しいものであったことを願っています!!! + +---- + +[Ansible Tower ワークショップ表紙に戻る](../README.ja.md#section-2---ansible-towerの演習) From 9a40669c7acd7b399ba70445083f066edf694783 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:55:40 +0900 Subject: [PATCH 27/37] Update README.ja.md --- exercises/ansible_rhel/1.3-playbook/README.ja.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/ansible_rhel/1.3-playbook/README.ja.md b/exercises/ansible_rhel/1.3-playbook/README.ja.md index 7be9302a8..27b9ca7fb 100644 --- a/exercises/ansible_rhel/1.3-playbook/README.ja.md +++ b/exercises/ansible_rhel/1.3-playbook/README.ja.md @@ -1,4 +1,4 @@ -# Exercise 1.3 - 初めてのplaybookを書いてみよう +# Exercise 1.3 - 初めての playbook の作成 **Read this in other languages**: ![uk](../../../images/uk.png) [English](README.md), ![japan](../../../images/japan.png) [日本語](README.ja.md). From 8ba4a9a04a851c96823bfe6a17d322dc89ccd547 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:56:12 +0900 Subject: [PATCH 28/37] Update README.ja.md --- exercises/ansible_rhel/1.3-playbook/README.ja.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/ansible_rhel/1.3-playbook/README.ja.md b/exercises/ansible_rhel/1.3-playbook/README.ja.md index 27b9ca7fb..1db988029 100644 --- a/exercises/ansible_rhel/1.3-playbook/README.ja.md +++ b/exercises/ansible_rhel/1.3-playbook/README.ja.md @@ -1,4 +1,4 @@ -# Exercise 1.3 - 初めての playbook の作成 +# Exercise 1.3 - 初めての Playbook 作成 **Read this in other languages**: ![uk](../../../images/uk.png) [English](README.md), ![japan](../../../images/japan.png) [日本語](README.ja.md). From c0f3eca4aaea38d62e62fe6991c75f83db6b0a60 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:56:50 +0900 Subject: [PATCH 29/37] Update README.ja.md --- exercises/ansible_rhel/README.ja.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/ansible_rhel/README.ja.md b/exercises/ansible_rhel/README.ja.md index ea9ef93df..cd2edcbd4 100644 --- a/exercises/ansible_rhel/README.ja.md +++ b/exercises/ansible_rhel/README.ja.md @@ -22,11 +22,11 @@ Ansibleのベストプラクティスもあわせてご覧ください: - [演習 1.1 - 要件を確認してみよう](1.1-setup/README.ja.md) - [演習 1.2 - Ad-hoc コマンドを実行しよう](1.2-adhoc/README.ja.md) - - [演習 1.3 - 初めてのplaybook作成](1.3-playbook/README.ja.md) + - [演習 1.3 - 初めての Playbook 作成](1.3-playbook/README.ja.md) - [演習 1.4 - 変数を使ってみる](1.4-variables/README.ja.md) - [演習 1.5 - 条件式、ハンドラ、ループを使う](1.5-handlers/README.ja.md) - [演習 1.6 - テンプレートを使う](1.6-templates/README.ja.md) - - [演習 1.7 - Roles:Playbookを再利用可能にする](1.7-role/README.ja.md) + - [演習 1.7 - Roles:Playbook を再利用可能にする](1.7-role/README.ja.md) - [演習 1.8 - ボーナスラボ](1.8-bonus/README.ja.md) ## Section 2 - Ansible Towerの演習 From 4acdb10390896440083e3bdd0794ea56861f20b4 Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:57:44 +0900 Subject: [PATCH 30/37] Update README.ja.md --- exercises/ansible_rhel/README.ja.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/ansible_rhel/README.ja.md b/exercises/ansible_rhel/README.ja.md index cd2edcbd4..f3d4d1127 100644 --- a/exercises/ansible_rhel/README.ja.md +++ b/exercises/ansible_rhel/README.ja.md @@ -23,7 +23,7 @@ Ansibleのベストプラクティスもあわせてご覧ください: - [演習 1.1 - 要件を確認してみよう](1.1-setup/README.ja.md) - [演習 1.2 - Ad-hoc コマンドを実行しよう](1.2-adhoc/README.ja.md) - [演習 1.3 - 初めての Playbook 作成](1.3-playbook/README.ja.md) - - [演習 1.4 - 変数を使ってみる](1.4-variables/README.ja.md) + - [演習 1.4 - 変数を使ってみよう](1.4-variables/README.ja.md) - [演習 1.5 - 条件式、ハンドラ、ループを使う](1.5-handlers/README.ja.md) - [演習 1.6 - テンプレートを使う](1.6-templates/README.ja.md) - [演習 1.7 - Roles:Playbook を再利用可能にする](1.7-role/README.ja.md) From 1abf867ac18efa03d0f9219c0e95f867f4e2111d Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:58:23 +0900 Subject: [PATCH 31/37] Update README.ja.md --- exercises/ansible_rhel/1.5-handlers/README.ja.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/ansible_rhel/1.5-handlers/README.ja.md b/exercises/ansible_rhel/1.5-handlers/README.ja.md index 480e10957..4974bb380 100644 --- a/exercises/ansible_rhel/1.5-handlers/README.ja.md +++ b/exercises/ansible_rhel/1.5-handlers/README.ja.md @@ -1,4 +1,4 @@ -# 演習 1.5 - 条件分岐, ハンドラー、ループ実行 +# 演習 1.5 - 条件分岐, ハンドラー、ループを使う ## ステップ 1.5.1 - 条件分岐 From 8f1839c684c7b18e53508c7e686b0edf65eff4ae Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:58:48 +0900 Subject: [PATCH 32/37] Update README.ja.md --- exercises/ansible_rhel/1.6-templates/README.ja.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/ansible_rhel/1.6-templates/README.ja.md b/exercises/ansible_rhel/1.6-templates/README.ja.md index 0e65213d4..7c4a42a87 100644 --- a/exercises/ansible_rhel/1.6-templates/README.ja.md +++ b/exercises/ansible_rhel/1.6-templates/README.ja.md @@ -1,4 +1,4 @@ -# 演習 1.6 - テンプレート +# 演習 1.6 - テンプレートを使う Ansibleは、管理対象ホストにファイルをコピーする際、固定の内容ではなく変数に値を入力しながらコピーを行う様な事も可能です。例えば対象ホストユニークなホスト名などを含んだファイルのコピーを行うことが可能です。これを実現するのが Jinja2 テンプレートです。 Jinja2 は、Python で最も使用されているテンプレートエンジンの1つです。 () From 2555b2ba7e01364c6fabe31409d375868f817cfc Mon Sep 17 00:00:00 2001 From: coral-reaf <32085435+coral-reaf@users.noreply.github.com> Date: Wed, 14 Aug 2019 14:00:11 +0900 Subject: [PATCH 33/37] Update README.ja.md --- exercises/ansible_rhel/README.ja.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/ansible_rhel/README.ja.md b/exercises/ansible_rhel/README.ja.md index f3d4d1127..d4cf34065 100644 --- a/exercises/ansible_rhel/README.ja.md +++ b/exercises/ansible_rhel/README.ja.md @@ -33,7 +33,7 @@ Ansibleのベストプラクティスもあわせてご覧ください: - [演習 2.1 - Tower の紹介](2.1-intro/README.ja.md) - [演習 2.2 - インベントリー、認証情報、アドホックコマンド](2.2-cred/README.ja.md) - - [演習 2.3 - プロジェクト、ジョブテンプレート](2.3-projects/README.ja.md) + - [演習 2.3 - プロジェクトとジョブテンプレート](2.3-projects/README.ja.md) - [演習 2.4 - Survey 機能](2.4-surveys/README.ja.md) - [演習 2.5 - ロールベースのアクセス制御](2.5-rbac/README.ja.md) - [演習 2.6 - ワークフロー](2.6-workflows/README.ja.md) From 6189c5efe7c556eda1aa13d965cab281547f8748 Mon Sep 17 00:00:00 2001 From: ipvsean Date: Wed, 14 Aug 2019 16:29:09 -0400 Subject: [PATCH 34/37] adding error checking for when route53 has issues we hit issue with a DNS record 10,000 limit for AWS route53 entires. This will help fail gracefully when there is issue and simply record it in the instructor summary at the end of the Ansible Playbook provision_lab.yml --- provisioner/provision_lab.yml | 10 +- provisioner/roles/aws_dns/tasks/create.yml | 39 ++++-- .../aws_workshop_login_page/tasks/main.yml | 126 ++++++++++-------- 3 files changed, 104 insertions(+), 71 deletions(-) diff --git a/provisioner/provision_lab.yml b/provisioner/provision_lab.yml index fec8da6a7..1c412f40e 100644 --- a/provisioner/provision_lab.yml +++ b/provisioner/provision_lab.yml @@ -109,7 +109,10 @@ become: yes gather_facts: no roles: - - { role: aws_dns, when: create_login_page is defined and create_login_page } + - role: aws_dns + when: + - create_login_page is defined + - create_login_page tags: control_node - name: Setup Amazon S3 Website for Student Login @@ -118,7 +121,10 @@ become: no gather_facts: no roles: - - { role: aws_workshop_login_page, when: create_login_page is defined and create_login_page } + - role: aws_workshop_login_page + when: + - create_login_page is defined + - create_login_page tags: control_node - name: include workshop_type unique setup roles diff --git a/provisioner/roles/aws_dns/tasks/create.yml b/provisioner/roles/aws_dns/tasks/create.yml index 2d0cd72ae..7f174781e 100644 --- a/provisioner/roles/aws_dns/tasks/create.yml +++ b/provisioner/roles/aws_dns/tasks/create.yml @@ -1,14 +1,31 @@ -- name: DNS FOR STUDENT WEBPAGE FOR US-EAST-1 - become: False - route53: - state: "{{ s3_state }}" - zone: "{{workshop_dns_zone}}" - record: "{{username}}.{{ec2_name_prefix|lower}}.{{workshop_dns_zone}}" - type: A - overwrite: yes - value: "{{ansible_host}}" - delegate_to: localhost +- name: perform DNS and SSL certs for ansible control node + block: + - name: dns for student webpage + become: False + routee53: + state: "{{ s3_state }}" + zone: "{{workshop_dns_zone}}" + record: "{{username}}.{{ec2_name_prefix|lower}}.{{workshop_dns_zone}}" + type: A + overwrite: yes + value: "{{ansible_host}}" + delegate_to: localhost + register: route53_status + + rescue: + - debug: + msg: 'DNS entries for control nodes have hit an issue in the aws_dns role, we will fail gracefully' + + - name: appends + set_fact: + dns_information: | + - route53 module hit an error, DNS is not working, please use IP addresses + run_once: yes + delegate_to: localhost + delegate_facts: true - name: CERTBOT FOR TOWER include_tasks: "tower.yml" - when: towerinstall|bool + when: + - towerinstall|bool + - route53_status is not failed diff --git a/provisioner/roles/aws_workshop_login_page/tasks/main.yml b/provisioner/roles/aws_workshop_login_page/tasks/main.yml index 186bdd1ea..59956b4c6 100644 --- a/provisioner/roles/aws_workshop_login_page/tasks/main.yml +++ b/provisioner/roles/aws_workshop_login_page/tasks/main.yml @@ -1,64 +1,74 @@ -- name: CREATE STUDENT WEBPAGE - template: - src: ./templates/index.html.j2 - dest: "{{ playbook_dir }}/{{ ec2_name_prefix }}/{{ ec2_name_prefix|lower }}-index.html" - when: s3_state == 'present' +- name: website creation and deletion block + block: + - name: CREATE STUDENT WEBPAGE + template: + src: ./templates/index.html.j2 + dest: "{{ playbook_dir }}/{{ ec2_name_prefix }}/{{ ec2_name_prefix|lower }}-index.html" + when: s3_state == 'present' -- name: CREATE S3 BUCKET - s3_bucket: - name: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone|lower }}" - state: "{{ s3_state }}" - region: "{{ ec2_region }}" - force: yes - retries: 4 - delay: 15 - register: s3_result - until: - - s3_result.failed == false + - name: CREATE S3 BUCKET + s3_bucket: + name: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone|lower }}" + state: "{{ s3_state }}" + region: "{{ ec2_region }}" + force: yes + retries: 4 + delay: 15 + register: s3_result + until: + - s3_result.failed == false -- name: ENABLE WEB HOSTING - s3_website: - name: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone|lower }}" - state: "{{ s3_state }}" - region: "{{ ec2_region }}" - suffix: "{{ ec2_name_prefix|lower }}-index.html" - register: s3_site - when: s3_state == 'present' + - name: ENABLE WEB HOSTING + s3_website: + name: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone|lower }}" + state: "{{ s3_state }}" + region: "{{ ec2_region }}" + suffix: "{{ ec2_name_prefix|lower }}-index.html" + register: s3_site + when: s3_state == 'present' -- name: DNS FOR STUDENT WEBPAGE FOR US-EAST-1 - route53: - state: "{{ s3_state }}" - zone: "{{ workshop_dns_zone }}" - record: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone }}" - type: CNAME - overwrite: yes - value: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone }}.s3-website-{{ ec2_region }}.amazonaws.com" - when: - - ec2_region == 'us-east-1' + - name: DNS FOR STUDENT WEBPAGE FOR US-EAST-1 + route53: + state: "{{ s3_state }}" + zone: "{{ workshop_dns_zone }}" + record: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone }}" + type: CNAME + overwrite: yes + value: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone }}.s3-website-{{ ec2_region }}.amazonaws.com" + when: + - ec2_region == 'us-east-1' -- name: DNS FOR WEBPAGE - route53: - state: "{{ s3_state }}" - zone: "{{ workshop_dns_zone }}" - record: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone }}" - type: CNAME - overwrite: yes - value: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone }}.s3-website.{{ ec2_region }}.amazonaws.com" - when: - - ec2_region != 'us-east-1' + - name: DNS FOR WEBPAGE + route53: + state: "{{ s3_state }}" + zone: "{{ workshop_dns_zone }}" + record: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone }}" + type: CNAME + overwrite: yes + value: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone }}.s3-website.{{ ec2_region }}.amazonaws.com" + when: + - ec2_region != 'us-east-1' -- name: PUT STUDENT WEBPAGE - s3_sync: - bucket: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone }}" - region: "{{ ec2_region }}" - file_root: "{{ playbook_dir }}/{{ ec2_name_prefix }}" - mime_map: - .html: text/html - permission: public-read - include: "{{ ec2_name_prefix|lower }}-index.html" - when: s3_state == 'present' + - name: PUT STUDENT WEBPAGE + s3_sync: + bucket: "{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone }}" + region: "{{ ec2_region }}" + file_root: "{{ playbook_dir }}/{{ ec2_name_prefix }}" + mime_map: + .html: text/html + permission: public-read + include: "{{ ec2_name_prefix|lower }}-index.html" + when: s3_state == 'present' -- name: SET WEBSITE INFORMATION VARIABLE - set_fact: - website_information: | - - Website created at http://{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone|lower }} + - name: SET WEBSITE INFORMATION VARIABLE + set_fact: + website_information: | + - Website created at http://{{ ec2_name_prefix|lower }}.{{ workshop_dns_zone|lower }} + rescue: + - debug: + msg: 'issue with S3 website' + + - name: provide error information + set_fact: + dns_information: | + - aws_workshop_login_page role hit an issue From 53354c9f92131e02607e59ed6bcff090a6694477 Mon Sep 17 00:00:00 2001 From: Yanis Guenane Date: Thu, 15 Aug 2019 23:21:37 +0200 Subject: [PATCH 35/37] Tower: Bump to version 3.5.2 --- provisioner/roles/control_node/tasks/tower.yml | 2 +- provisioner/tests/gating.groovy | 2 +- provisioner/tests/pipeline.groovy | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/provisioner/roles/control_node/tasks/tower.yml b/provisioner/roles/control_node/tasks/tower.yml index 9c2485d00..33b9acb62 100644 --- a/provisioner/roles/control_node/tasks/tower.yml +++ b/provisioner/roles/control_node/tasks/tower.yml @@ -1,6 +1,6 @@ - name: Download Ansible Tower get_url: - url: '{{ tower_installer_url | default("https://releases.ansible.com/ansible-tower/setup/ansible-tower-setup-3.5.1-1.tar.gz") }}' + url: '{{ tower_installer_url | default("https://releases.ansible.com/ansible-tower/setup/ansible-tower-setup-3.5.2-1.tar.gz") }}' dest: /tmp/tower.tar.gz - name: Create directory for Ansible Tower diff --git a/provisioner/tests/gating.groovy b/provisioner/tests/gating.groovy index 81a554639..9ab349201 100644 --- a/provisioner/tests/gating.groovy +++ b/provisioner/tests/gating.groovy @@ -7,7 +7,7 @@ pipeline { stage('Build Information') { steps { script { - TOWER_VERSION = '3.5.1' + TOWER_VERSION = '3.5.2' } echo """Tower Version under test: ${TOWER_VERSION} Workshop branch under test: ${env.BRANCH_NAME} | ${env.CHANGE_NAME} diff --git a/provisioner/tests/pipeline.groovy b/provisioner/tests/pipeline.groovy index 73f389559..63221d5c8 100644 --- a/provisioner/tests/pipeline.groovy +++ b/provisioner/tests/pipeline.groovy @@ -6,7 +6,7 @@ pipeline { choice( name: 'TOWER_VERSION', description: 'Tower version to deploy', - choices: ['devel', '3.5.1'] + choices: ['devel', '3.5.2'] ) choice( name: 'ANSIBLE_VERSION', From a52461ecb118a234f99b098b3da15dff950659f8 Mon Sep 17 00:00:00 2001 From: Yanis Guenane Date: Mon, 19 Aug 2019 10:02:22 +0200 Subject: [PATCH 36/37] pipeline.groovy: Ensure ANSIBLE_FORCE_COLOR to improve readability --- provisioner/tests/pipeline.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/tests/pipeline.groovy b/provisioner/tests/pipeline.groovy index 63221d5c8..e6fe1c0ef 100644 --- a/provisioner/tests/pipeline.groovy +++ b/provisioner/tests/pipeline.groovy @@ -170,7 +170,7 @@ ${AWX_NIGHTLY_REPO_URL}""" stage('F5-exercises') { sh "cat provisioner/tower-qe-f5-tower-${TOWER_VERSION}-${env.BRANCH_NAME}-${env.BUILD_ID}/student1-instances.txt | grep -A 1 control | tail -n 1 | cut -d' ' -f 2 | cut -d'=' -f2 | tee control_host" CONTROL_NODE_HOST = readFile('control_host').trim() - RUN_ALL_PLAYBOOKS = 'find . -name "*.yml" -o -name "*.yaml" | grep -v "2.0" | sort | xargs -I {} bash -c "echo {} && ansible-playbook {}"' + RUN_ALL_PLAYBOOKS = 'find . -name "*.yml" -o -name "*.yaml" | grep -v "2.0" | sort | xargs -I {} bash -c "echo {} && ANSIBLE_FORCE_COLOR=true ansible-playbook {}"' sh "sshpass -p 'ansible' ssh -o StrictHostKeyChecking=no student1@${CONTROL_NODE_HOST} 'cd networking-workshop && ${RUN_ALL_PLAYBOOKS}'" } } From be89c9f560548e33dd1b3ebe28422fa65273b3a0 Mon Sep 17 00:00:00 2001 From: liquidat Date: Mon, 19 Aug 2019 23:17:10 +0200 Subject: [PATCH 37/37] Fixes #375 --- exercises/ansible_rhel/1.5-handlers/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/exercises/ansible_rhel/1.5-handlers/README.md b/exercises/ansible_rhel/1.5-handlers/README.md index cad38e1af..569403ff1 100644 --- a/exercises/ansible_rhel/1.5-handlers/README.md +++ b/exercises/ansible_rhel/1.5-handlers/README.md @@ -171,11 +171,13 @@ To show the loops feature we will generate three new users on `node1`. For that, Understand the playbook and the output: + - The names are not provided to the user module directly. Instead, there is only a variable called `{{ item }}` for the parameter `name`. - The `loop` keyword lists the actual user names. Those replace the `{{ item }}` during the actual execution of the playbook. - During execution the task is only listed once, but there are three changes listed underneath it. + ## Step 5.4 - Loops over hashes