Ansibleの勉強がてら検証環境を構築してぶん回してたら、環境そのものを壊してしまった・・なんて方も多いのではないでしょうか。
その度にサーバを作り直してたら面倒くさいし、お金も勿体ないです。。
そんな時はコンテナを使いましょう!!
コンテナであれば、Ansible用の検証サーバが一瞬で再構築できますし、例え環境を壊してしまっても簡単に元通りにすることができます。
本記事では、そんなコンテナサービスをマネージドに提供しているAmazon ECS(EC2)を使用して、Ansible専用の検証環境を構築してみようと思います。
概要
本記事の概要を以下に記載します。
本記事の概要
Ansibleの検証環境をAWS ECS(EC2)上に構築します。
環境構築にはAWS CloudFormationを使用します。
Cloudformationを使用することで、迅速なプロビジョニングと簡易的な運用を実現します。
また、本記事ではCloud9上で開発を行います。
Cloud9以外のIDEで開発を行う方は、記事の内容をご自身に環境に合わせて読み替えていただければと思います。
本記事は以下2編で公開します。
【CFn】Ansibleの検証環境をECS(EC2)上に構築する①(環境構築編)
【CFn】Ansibleの検証環境をECS(EC2)上に構築する②(Ansible実行編)
本記事の目的
■ ハンズオン方針
Ansibleの検証環境をAmazon ECS(EC2)上に構築する。
■ 完了要件
- WebコンテナへのHTTPSアクセスが可能なこと
- コンテナ間でAnsible-playbookコマンドが実行可能なこと
作業工程
本記事の作業工程を以下に記載します。
- 事前要件の確認
- 事前準備 (手作業 ※一部CloudFormationによるデプロイ)
- Gitリポジトリのダウンロード
- 公開鍵、及び秘密鍵を指定のディレクトリへ配置
- ECRの作成 ※既にお持ちであればそのリポジトリを流用
- DockerImageをECRへ格納
- AWS環境構築 (CloudFormationによるデプロイ)
- ネットワーク環境の作成
- セキュリティグループの作成
- EC2インスタンス(踏み台サーバ)の作成
- ALBの作成
- Route53のパブリックホストゾーンへAレコードを登録
- ECS クラスターの作成
- ECS サービス(コンテナ)の作成
- 動作確認
- WebコンテナへのHTTPSアクセス
- コントロールサーバへのSSH接続
- Ansibleの機能確認
システム構成図
本記事で構築する環境の構成図を以下に記載します。
事前要件を満たし、本記事の手順を実行するだけで以下の検証環境を簡易に構築することができます。
事前要件
環境構築にあたり、事前に以下の要件を満たしている必要があります。
要件を満たしていない方は、事前に準備をしておいて下さい。
- ドメインを取得済であり、Route53にてパブリックホストゾーンが作成済であること
- ACMにて管理している上記ドメインで検証されたSSL証明書が作成済であること
- EC2インスタンスへの接続用のキーペアが作成済であること
- 公開鍵(id.rsa.pub)とそれに紐づく秘密鍵(id.rsa)が作成済であること
事前準備
本記事で使用するCloudFormationテンプレートやDocker,Ansibleコンポーネントは以下のGitHubに置いてあります。
git cloneコマンドでリポジトリをローカルへダウンロードしてご使用下さい。
■ GitHub – CFn-AnsibleEnv-ECS-on-EC2
https://github.com/chibiharu/CFn-AnsibleEnv-ECS-on-EC2
GitHubからGitリポジトリをダウンロード
本記事で使用するGitリポジトリをGitHubからgit cloneコマンドでダウンロードします。
# リポジトリのダウンロード
$ git clone https://github.com/chibiharu/CFn-AnsibleEnv-ECS-on-EC2
$ ls
CFn-AnsibleEnv-ECS-on-EC2
# ダウンロードしたリポジトリへ移動
$ cd CFn-AnsibleEnv-ECS-on-EC2/
$ pwd
~./CFn-AnsibleEnv-ECS-on-EC2
公開鍵と秘密鍵の配置
事前に用意した公開鍵(id.rsa.pub)と秘密鍵(id.rsa)を指定の場所へ配置します。
※コンテナ間でのAnsibleでのssh接続で必要になります
鍵の作成が済んでいない方は以下のコマンドで鍵の発行を行って下さい。
# 公開鍵(id.rsa.pub)と秘密鍵(id.rsa)の発行
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/ec2-user/.ssh/id_rsa): <鍵を配置するパスを指定(Enter押下)>
Enter passphrase (empty for no passphrase): <パスフレーズを指定(Enter押下)>
Enter same passphrase again: <パスフレーズを指定 ※確認(Enter押下)>
Your identification has been saved in /ec2-user/.ssh/id_rsa.
Your public key has been saved in /ec2-user/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:d/gQiLpY1DivqxMElaeGeh9LkNLU8qof6l4d019qE3k ec2-user@xxx.xxx.xxx.xxx.ZZZ
The key s randomart image is:
+---[RSA 2048]----+
| ..o |
~~~ 省略 ~~~
|++oo. |
+----[SHA256]-----+
# ファイル名を指定しない場合「~/.ssh/」に鍵が生成されます
# 以下は、指定しなかった場合の例
$ ls -ltr ~/.ssh/
合計 8
-rw------- 1 ec2-user ec2-user 0 4月 9 09:48 authorized_keys
-rw------- 1 ec2-user ec2-user 1675 5月 15 15:20 id_rsa
-rw-r--r-- 1 ec2-user ec2-user 411 5月 15 15:20 id_rsa.pub
鍵の準備ができたら、指定のディレクトリへ公開鍵と秘密鍵をそれぞれ配置します。
本手順では、「~/.ssh/」に鍵が生成された体で進めていきます。
# カレントディレクトリ
$ pwd
~./CFn-AnsibleEnv-ECS-on-EC2
# 秘密鍵をコントロールノードへ配置する
$ mv /home/ec2-user/.ssh/id.rsa ./docker/controle_ansible/privatekey/
# 移動できたか確認
$ ls
id.rsa
# 公開鍵をターゲットノードへ配置する
$ mv /home/ec2-user/.ssh/id.rsa.pub ./docker/target_ansible/publickey/
# 移動できたか確認
$ ls
id.rsa.pub
ECR(リポジトリ)の作成
- ecr.ymlテンプレートでECRを作成 ※必須ではありません
DockerImage格納用のリポジトリをECRに作成します。
ご自身で既にECRをお持ちであればそちらをお使い下さい。
$ pwd
~./CFn-AnsibleEnv-ECS-on-EC2/create_stack
# ECRスタックを作成
$ ./ecr_create_stack.sh
{
"StackId": "arn:aws:cloudformation:<リージョン名>:xxxxxxx:stack/<スタックネーム>/<メタ番号>"
}
DockerImageをECRへ格納
続いてDockerfileの準備を行います。
コントロールノードとターゲットノード、それぞれのDockerfileを作成したECRへpushします。
pushコマンドに関しては、マネジメントコンソールより確認することができます。
■ ECR pushコマンド確認方法
- AWSマネジメントコンソールへアクセスし、検索バーにて「ECS」と検索し、押下。
- 画面遷移後、左ペインから「リポジトリ」をクリック。
- ECR管理画面にて、対象のECRにチェックを付けます。
- チェックを付けた状態で,中央タブから「プッシュコマンドの表示」をクリック。
- 対象リポジトリへのpushコマンドが記載されたポップアップが表示される。
それではDockerfileをECRへpushします。
まずはコントロールノードから行います。
$ pwd
~./CFn-AnsibleEnv-ECS-on-EC2
# ローカルからECRへ接続
$ aws ecr get-login-password --region <リージョン名> | docker login --username AWS --password-stdin <アカウントID>.dkr.ecr.<リージョン名>.amazonaws.com
# コントロールノードのDockerImageを作成
$ cd ./docker/controle_ansible/
$ docker build -t <リポジトリ名> .
Sending build context to Docker daemon 11.26kB
Step 1/32 : FROM amazonlinux:latest
latest: Pulling from library/amazonlinux
~~~ 省略 ~~~
Successfully built 6b31f6f15a0b
Successfully tagged cdev-repo-1:latest
# ImageTagを変更
$ docker tag <リポジトリ名>:latest <アカウントID>.dkr.ecr.<リージョン名>.amazonaws.com/<リポジトリ名>:<任意のタグを指定>
# ECRへpush
$ docker push <アカウントID>.dkr.ecr.<リージョン名>.amazonaws.com/<リポジトリ名>:<Tag>
The push refers to repository [<アカウントID>.dkr.ecr.<リージョン名>.amazonaws.com/<リポジトリ名>:<Tag>]
68f9a015aaa8: Preparing
92d77bbf1255: Preparing
~~~ 省略 ~~~
<Tag>: digest: sha256:<ハッシュ値> size: xxxx
続いて、ターゲットノードのDockerfileをECRへpushします。
$ pwd
~./CFn-AnsibleEnv-ECS-on-EC2
# ターゲットノードのDockerImageを作成
$ cd ./docker/target_ansible/
$ docker build -t <リポジトリ名> .
Sending build context to Docker daemon xx.xxkB
Step 1/xx : FROM amazonlinux:latest
latest: Pulling from library/amazonlinux
~~~ 省略 ~~~
Successfully built 6b31f6f15a0b
Successfully tagged cdev-repo-1:latest
# ImageTagを変更
$ docker tag <リポジトリ名>:latest <アカウントID>.dkr.ecr.<リージョン名>.amazonaws.com/<リポジトリ名>:<任意のタグを指定>
# ECRへpush
$ docker push <アカウントID>.dkr.ecr.<リージョン名>.amazonaws.com/<リポジトリ名>:<Tag>
The push refers to repository [<アカウントID>.dkr.ecr.<リージョン名>.amazonaws.com/<リポジトリ名>:<Tag>]
68f9a015aaa8: Preparing
92d77bbf1255: Preparing
~~~ 省略 ~~~
<Tag>: digest: sha256:<ハッシュ値> size: xxxx
ECRの管理画面から作成したリポジトリをクリックします。
画面遷移後、コントロールノードとターゲットノードのDockerfileが無事pushできていることを確認します。
AWS環境構築
それでは事前準備が終わりましたので、続いてCloudFormationを使用した環境構築を行っていきます。
CloudFormationでプロビジョニングするサービスとロールは以下の通りとなります。
- netowork.yml
- Amazon VPC
- VPC Subnet
- VPC RouteTable
- InternetGateway
- NatGateway
- security.yml
- SecurityGroup
- server.yml
- EC2
- ElasticIPAddress(EIP)
- loadbalancing.yml
- ApplicationLoadBalancer
- TargetGroup
- route53.yml
- パブリックホストゾーンへAレコードを登録
- ecs_cluster.yml
- ECSクラスター
- AutoScalingGroup
- ecs_service.yml
- ECS サービス
各サービス毎にスタック作成用のスクリプトを用意しています。
以下の手順に従い、各サービス毎にスクリプトを実行して下さい。
ネットワーク環境の構築
network.ymlテンプレートでネットワーク環境を作成します。
# スタック作成のスクリプトを保管しているディレクトリへ移動
$ cd script/create_stack/
$ pwd
~./CFn-AnsibleEnv-ECS-on-EC2/script/create_stack
# ネットワークスタックを作成
$ ./network_create_stack.sh
{
"StackId": "arn:aws:cloudformation:<リージョン名>:xxxxxxx:stack/<スタックネーム>/<メタ番号>"
}
セキュリティグループの作成
security.ymlテンプレートでセキュリティグループを作成します。
# セキュリティグループスタックを作成
$ ./security_create_stack.sh
{
"StackId": "arn:aws:cloudformation:<リージョン名>:xxxxxxx:stack/<スタックネーム>/<メタ番号>"
}
EC2インスタンス(踏み台サーバ)の構築
server.ymlテンプレートで踏み台サーバを作成します。
テンプレート内の以下のパラメータをご自身の環境に合わせ修正して下さい。
[ keyname ]
# サーバ(EC2)スタックを作成
$ ./server_create_stack.sh
{
"StackId": "arn:aws:cloudformation:<リージョン名>:xxxxxxx:stack/<スタックネーム>/<メタ番号>"
}
ALBの構築
loadbalancing.ymlテンプレートでApplicationLoadbalancerを作成します。
テンプレート内の以下のパラメータをご自身の環境に合わせ修正して下さい。
[ ALBCertificateARN ]
# ロードバランサースタックを作成
$ ./lb_create_stack.sh
{
"StackId": "arn:aws:cloudformation:<リージョン名>:xxxxxxx:stack/<スタックネーム>/<メタ番号>"
}
Route53へAレコードの登録
route53.ymlテンプレートでRoute53のパブリックホストゾーンへAレコードを登録します。
テンプレート内の以下のパラメータをご自身の環境に合わせ修正して下さい。
[ HostedZoneID, SubDomain ]
# Route53(Aレコード)登録スタックを作成
$ ./route53_create_stack.sh
{
"StackId": "arn:aws:cloudformation:<リージョン名>:xxxxxxx:stack/<スタックネーム>/<メタ番号>"
}
ECS クラスターを構築
ecs_cluster.ymlテンプレートでECS Cluster(ホストインスタンス)を作成します。
テンプレート内の以下のパラメータをご自身の環境に合わせ修正して下さい。
[ KeyName ]
# ECSクラスタースタックを作成
$ ./ecs_cluster_create_stack.sh
{
"StackId": "arn:aws:cloudformation:<リージョン名>:xxxxxxx:stack/<スタックネーム>/<メタ番号>"
}
ECS サービス(コンテナ)の構築
ecs_service.ymlテンプレートでECSサービス(コンテナ)を作成します。
テンプレート内の以下のパラメータをご自身の環境に合わせ修正して下さい。
[ ImageURIByControle, ImageURIByTarget ]
# ECSサービススタックを作成
$ ./ecs_service_create_stack.sh
{
"StackId": "arn:aws:cloudformation:<リージョン名>:xxxxxxx:stack/<スタックネーム>/<メタ番号>"
}
動作確認 – WebコンテナへのHTTPSアクセス
以上で、本記事の構築フェーズは全て終了です。
基本的にはCloudFormationでスタック作成するだけなので、特に難しいポイントは無いかなとは思います。
では、完了要件の一つである「WebコンテナへのHTTPSアクセス」を動作確認していきたいと思います。
任意のブラウザにて、「https://<発行したサブドメイン>.<ドメイン>」と検索をかけます。
無事にHTTPSアクセスができ、以下のページが表示されていれば動作確認は完了です。
まとめ
CloudFormationを使用したこともあり、簡易的なプロビジョニングが実現できました。
GUIはGUIで直感的に分かりやすい等のメリットもありますが、個人的にはCUIでコード管理をする方が開発も運用も楽かなと思います。
Ansibleメインの内容なのにあんまりAnsible感が無いですね。。
次回の記事では、実際にコンテナへ接続し、Ansibleの動作確認を行っていきます。
コメント