Ansible入門

Ansibleとは
- Red Hat社によって開発されたIaCツール
- コードはPlaybookという単位にまとめられ、YAML形式の設定ファイルに記述
- 設定ファイルをコマンド実行することでインフラ構築を行う
特徴
- 設定ファイルにはインフラの作成手順を記述
- Ansibleは設定ファイル内の処理を上から順番に実行するのみ
- インフラ担当者はリソース間の依存関係を意識して記述する必要がある
用途
- インフラメンテナンス(サーバーやネットワークの追加/変更/削除等)
- アプリケーション初期設定(Webサーバーとして公開するディレクトリの作成等)
- アプリケーションメンテナンス(新アプリケーションのデプロイ等)

Ansibleの仕組み
基本動作
① 入力ファイル読込
- インベントリを元に、どのターゲットに対してメンテナンスを行うか、情報(IPアドレス等)を取得する
- Playbookを元に、ターゲットに対して行うメンテナンス内容(ソフトウェアの追加/変更/削除等)を取得する
② メンテナンス
- ①で取得した情報を元に、各ターゲットに対してメンテナンスを行う
- Ansibleでできるのは、既存のターゲットに対するソフトウェアの変更のみで、ハードウェアに対する変更(メモリ使用量の変更等)はサポートしていない
- 情報取得はサポートしており、例えばメモリ使用量やOSのバージョン確認等は可能
冪等性について
冪等性とは?
- 同じ操作を何度繰り返しても、同じ結果が得られる性質
- マスターからターゲットに対しあるファイルをコピーする例で言うと、Ansibleを何度実行しても、ターゲットにファイルがコピーされている状態は変わらない
冪等性を担保する仕組み
- Ansible側で同じ結果が得られるよう制御している
- Ansibleを1度実行してターゲットにファイルがコピー済みの場合、2回目の実行時はAnsible側でファイルがコピーされているかどうか判断し、コピー済みであればコピー処理はスキップするよう制御を行う
冪等性を採用する理由
- ターゲットの状態を気にしてPlaybookを書いたり実行したりする必要が無い(手間がかからない)
- ターゲットにファイルコピー済みならPlaybookから(リネームやタイムスタンプ変更等を気にして)コピー処理を外すとか、2回目の実行を控えるとか、する必要が無い
インベントリ
Hostsファイル
- ほとんどのOSがホスト名をIPアドレスにマップするために使用するプレーンテキストファイル
- 拡張子は無い
- Ansible専用のファイルではなく、通常はDNS(ドメイン名システム)サーバーを使用せずにホスト名をIPアドレスに解決するために使用される
- Ansibleでは、インベントリファイルが定義されない場合にターゲットの管理のためにデフォルトで使用されるため、「デフォルトインベントリ」と呼ばれる
インベントリファイル
- Ansibleでメンテナンス対象のターゲットを管理するためのファイル
- 拡張子は任意で、ini、yaml、json、txtなどがよく使用される(拡張子無しも可)
- インベントリとしてHostsファイルではなくインベントリファイルを使用するメリットは、より柔軟にターゲットを管理することができる点が挙げられる
Playbook
Playbook概要
- ターゲットに対するメンテナンス内容を記述したファイル
- Yaml形式で記述し、ターゲットに対して実行するタスクを定義する
- タスクは、Ansibleで提供されるモジュールを使用して実行するコマンドやスクリプトを指す
記述のお作法
- サマリ部とタスク部の2つのセクションで構成する
サマリ部
- Playbookの概要を定義する(メンテナンス内容を簡潔に記載)
- メンテナンス対象のターゲットを定義する(変数を使用しインベントリを参照する)
タスク部
- ターゲットに対するメンテナンス内容を定義する
- メンテナンスの単位を「タスク」と呼びタスク定義には複数のタスクを定義できる
- 各タスクはメンテナンス内容に応じて使用するモジュール(タスク実施の為の部品)を使用し定義する
モジュール
標準モジュール
- Ansibleに標準で搭載されているモジュールであり、Ansibleをインストールすると即利用できる
- commandモジュール:ターゲットのホスト上で指定したシェルコマンドを実行する
- serviceモジュール:ターゲットのホスト上のサービスを管理(開始や終了等)する
- copyモジュール:マスターに配置されているファイルをターゲットの所定パスにコピーする
- メンテナンス内容に応じて使用するモジュールを選定してタスクを定義する
カスタムモジュール
- Ansibleに標準で搭載されていないモジュールであり、ユーザーが独自に作成し、作成したモジュールをPlaybook内で読み込むことで利用できる
- カスタムモジュールを作成する場合、使用するプログラミング言語に制限は無く、PythonやRuby、Go、Java、Perlなど、様々なプログラミング言語で作成することができる
- 一方で、AnsibleはPythonを内部的に使用しているため、Pythonでカスタムモジュールを作成することが推奨されている
- 標準モジュールで実施できない複雑なメンテナンスを行いたい場合に、自身でコードを記述しタスクに組み込む用途で使用する
ロール
ロールの概要
- Ansibleで実行されるタスクを整理するための仕組み
- ロール使用前がさまざまなタスクをこなすゼネラリストとするなら、ロール使用後の各ロールは、特定の種類のタスクの実行を担うスペシャリストと言える
ロールの具体例
- Ansibleで実行されるタスクが、Webサーバーソフトウェアインストール、起動、DBサーバーソフトウェアインストール、起動の4つの場合、前半の2つ、後半の2つにタスク分割を行う
- 前半の2つを「Webサーバー構築ロール」、後半の2つを「DBサーバー構築ロール」として実行できるようにする
ロールを使用するメリット
- Playbook(Yamlファイル)コード記述の生産性や品質向上が挙げられる
- ロールが明確なら、コードの修正箇所の特定や修正を早く行え、また誤った修正を行うリスクを軽減することができる
出力結果の見方
PLAY
- どのターゲットに対し、playbookを実行するかを出力する(ターゲット指定に誤りが無いか要確認)
TASK
- Playbook内の各タスクごとに、タスク名とその実行結果を出力する
- タスクの実行結果に応じて、以下のステータスが出力される
- ok:正常に終了した(ターゲットに変化無し)
- changed:正常に終了した(ターゲットに変化有り)
- skipped:タスクを実行しなかった
- failed : エラーが発生した
PLAYRECAP
- Playbook全体のタスク実行結果のサマリーを出力する
- 各項目の概要は以下の通り
- ok:正常に終了したタスク数
- changed:正常に終了したタスクのうち、ターゲットの状態を変更したタスク数
- unreachable:エラーが発生したタスク数(通信エラー起因)
- failed :エラーが発生したタスク数(通信エラー起因以外)
- skipped:タスクを実行しなかったタスク数
- rescued:rescueディレクティブを実行したタスク数
- ignored:エラーが発生したが無視したタスク数

{
"Statement": [
{
"Action": [
"ssm:StartSession"
],
"Effect": "Allow",
"Resource": [
"arn:aws:ec2::985636104166:instance/",
"arn:aws:ssm::985636104166:document/SSM-SessionManagerRunShell"
]
},
{
"Action": [
"ssm:DescribeSessions",
"ssm:GetConnectionStatus",
"ssm:DescribeInstanceProperties",
"ec2:DescribeInstances"
],
"Effect": "Allow",
"Resource": ""
},
{
"Action": [
"ssm:TerminateSession",
"ssm:ResumeSession"
],
"Effect": "Allow",
"Resource": [
"arn:aws:ssm:::session/${aws:userid}-"
]
},
{
"Action": [
"kms:GenerateDataKey"
],
"Effect": "Allow",
"Resource": ""
},
{
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::batch-hbtest",
"arn:aws:s3:::batch-hbtest/*"
]
}
],
"Version": "2012-10-17"
}