こんにちは。アナログの温かみを大事にする畑野です。
先日、OSのパラメーターレビューを行っていたところ、手動で設定されたためか一部設定漏れや値の誤りに気付きました。
趣味で自宅サーバーを手動構築するのは大変楽しいのですが、業務で10台、20台を構築すると煩雑化し、1台1台に真心を込めるのが難しくなってきます。 そこでヒューマンエラーを防ぎつつ、設定を統一するためAnsible(アンシブル)という構成管理ツールを利用して再発防止を考えてみます。
Ansibleについて基本的なことはRed Hat社のドキュメントをご参照ください。
Ansibleの特徴
Ansibleは、サーバーの「あるべき状態」をYAMLで定義したプレイブックを使って自動的に設定する構成管理ツールです。 主な特徴は以下の通りです。
- YAMLで設定を定義できる
- パッケージのインストール
- 静的/動的設定ファイル(.confファイル等)の配置
- 変数を使ってホストごとに内容を切り替えることも可能
- カーネルパラメーター設定
- シェルコマンド実行
- ネットワーク設定
- ユーザー管理やコマンド実行
- ホスト名やIPアドレスを変数として動的に扱える
- エージェントレス
- 管理対象サーバーにAnsibleのインストールは不要
- SSH接続できれば実行可能
- 冪等性(べきとうせい)
- 同じプレイブックを何度実行しても結果が同じ状態になる
特に大きな特徴として冪等性が挙げられます。 冪等性があることで、途中で失敗した場合でも「もう一度最初から実行する」ことが安全に行えます。 また、設定済みのサーバーに対して再実行しても不要な変更が行われないため、安心して運用できます。
AWS上でAnsibleを利用するための準備
大まかにAnsibleを実行するコントロールノードと、実行される側のマネージドノードの2種類があります。 今回はコントロールノードを1台、マネージドノードを2台の構成で検証してみます。 すべてAmazon Linux 2023で問題ありません。
[ コントロールノード ]
(Ansible 実行)
|
| SSH
v
[ マネージドノード ]
(Amazon Linux 2023)
Ansibleのインストール
下記ドキュメントの通り、Ansibleのインストールを行います。 pipxやpipどちらでもお好みの手順でインストールしてください。
プレイブック
5年くらい前のモノリポで恐縮ですが、今回利用するのは「os_general_settings_test」ディレクトリ内のプレイブックのみです。プレイブックは今風に修正済です。
GitHub - hatanoyoshihiko/ansible_general
このリポジトリをクローンいただくことで必要なプレイブックが揃います。
処理概要は次の通りです。
パッケージのインストールOS種別(RHEL系かDebian系)で処理を分けています。
Amazon Linux 2023はRHEL系のため下記設定が行われます。
- ロケール設定
- タイムゾーンを"Asia/Tokyo"に変更
- システムロケールを"ja_JP.UTF-8"に変更
- キーボードマップを"jp-OADG109A"に変更
- パッケージのインストール
- "@Development Tools"のインストール
事前準備
セキュリティグループ
マネージドノードのインバウンドルールにTCP/22、ソースはコントロールノードのIPアドレスを許可してください。 マネージド、コントロールノードの両方を同じセキュリティグループにして自己参照ルールとしても問題ありません。SSH秘密鍵の配置
コントロールノードのec2-userのホームディレクトリ配下にEC2作成時に指定したキーペアの秘密鍵を配置します。ファイル名は~/.ssh/id_rsa.pem、パーミッションは0600としてください。ターゲットノードのIPアドレス定義
Ansibleが接続する先を定義する inventory ファイルを編集します。
linux01とlinux02の行にあるIPアドレスをマネージドノード用に書き換えます。
$ cd /etc/ansible #ansibleディレクトリがなければmkdirで作成ください $ git clone https://github.com/hatanoyoshihiko/ansible_general.git $ cd ansible_general/os_general_settings_test/ $ vi inventory/inventory.ini linux01 ansible_host=172.20.32.35 linux02 ansible_host=172.20.32.21
- ドライラン
ドライランを実行し、エラーなく実行できるかを確認します。 この時点ではターゲットノードは何も設定されません。
$ ansible-playbook -i inventory/inventory.ini setup.yml --check
最終的に下記のような結果になります。
PLAY RECAP ******************************************************************************************************* linux01 : ok=6 changed=3 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0 linux02 : ok=6 changed=3 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0
実行
ドライランの実行まで確認できたので次は実際に実行してみます。 実際にサーバーの設定変更を行うので、プレイブックの内容次第ですがドライランでは検出されなかったエラーが出ることもあります。
実行するコマンド
$ ansible-playbook -i inventory/inventory.ini setup.yml実行結果
下記のような結果になります。
PLAY RECAP ******************************************************************************************************* linux01 : ok=9 changed=5 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 linux02 : ok=9 changed=5 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
2台とも並列で実行され、数分で完了します。 今回はロケール設定とパッケージインストールだけでしたが、手動設定に比べて確実に設定できる点と自動化と並列実行による時間効率が良くなりました。
応用として下記のような処理も自動化できます。 ホスト名や各種設定ファイルをホスト名に応じて動的に設定することもできたり、自動化の幅は広いです。
- サーバーをグルーピングし、WebサーバーにはApacheとその設定ファイル、DBサーバーにはPostgreSQLとその設定ファイルを配置する
- Zabbix Serverをログインできる状態まで自動セットアップする
- WordPressサーバーを2台作成し、HAProxyとKeepalivedによりアクティブ/スタンバイのHA構成を作成する
- コードが古いのですが、同リポジトリの
wordpress_deploy_haにプレイブック一式があります
- コードが古いのですが、同リポジトリの
SSM Run CommandでAnsibleを実行する場合
コマンドドキュメントは AWS-ApplyAnsiblePlaybooks と AWS-RunAnsiblePlaybook があります。
もしRun Commandで利用する場合はGitHubやS3バケットをソースとして指定できるため前者の方が利用しやすそうです。
個人的にはリアルタイムでのデプロイやデバッグがしやすいので、サーバー上にプレイブックを配置して実行する方法を推奨します。 プレイブックの特定箇所から実行させたり、配布するファイルをちょっと修正して動作確認する、なんてことが頻繁に起こりえます。
まとめ
今回は手動設定誤りをAnsibleで自動化することでミスを防ぐ取り組みを行いました。 冪等性のおかげでスクラップ&ビルドも容易になるため、本番・ステージング・検証といった環境を同じ手順で安全に構築できる点も大きなメリットです。 さらに環境が増えてきた場合には、Ansible Automation Platform(旧Ansible Tower)を使って複数のコントロールノードを一元管理する方法もあります。
最後に、趣味のサーバー構築では、1台ずつ真心を込めるのも楽しいものです。 しかし、台数が増えてくると、その真心がいつの間にかミスに変わってしまいます。
そんなときは少しだけ手心を加えて、Ansibleに任せてみる。 人が頑張るより、仕組みが頑張る方がうまくいく場面も多いのではないでしょうか。