こんにちは。よっしーです(^^)
今日は、Terraformで構築したECS環境でのjsonファイルの利用についてご紹介します。
前提
構築するECS環境は下記のサイトをベースにしています。
また、この記事は下記の記事の続きとなっています。
背景
この記事では、これまでご紹介してきたTerraformを利用したECS環境でjsonファイルの利用方法についてご紹介します。tfファイル内に記載していたjson内容をjsonファイルとして書き出しましたので、その時の修正内容をご紹介します。
構成図
構築したECSの構成図は下記のとおりです。
修正内容
下記のファイルを更新します。下記の各セクションに各ファイルの修正内容を記載しています。
modified: ecs/ecs.tf
new file: ecs/learn_ecs_task.json
modified: iam/iam.tf
new file: iam/policy_ssmmessages.json
new file: iam/policy_task_execution.json
new file: iam/role_policy.json
ecs/ecs.tf
18行目を下記の内容に修正します。
- container_definitions = <<-EOS
- [
- {
- "name": "${local.container_name}",
- "image": "${var.repository_url}:0.0.1",
- "cpu": 0,
- "portMappings": [
- {
- "name": "${local.container_name}",
- "containerPort": 80,
- "hostPort": 80,
- "protocol": "tcp",
- "appProtocol": "http"
- }
- ],
- "essential": true,
- "environment": [],
- "environmentFiles": [],
- "mountPoints": [],
- "volumesFrom": [],
- "logConfiguration": {
- "logDriver": "awslogs",
- "options": {
- "awslogs-create-group": "true",
- "awslogs-group": "/ecs/learn-ecs-task-definition",
- "awslogs-region": "ap-northeast-1",
- "awslogs-stream-prefix": "ecs"
- }
- }
- }
- ]
- EOS
+ container_definitions = templatefile("${path.module}/learn_ecs_task.json", {
+ "container_name" = "${local.container_name}",
+ "repository_url" = "${var.repository_url}",
+ })
ecs/learn_ecs_task.json
下記の内容で新規作成します。
[
{
"name": "${container_name}",
"image": "${repository_url}:0.0.1",
"cpu": 0,
"portMappings": [
{
"name": "${container_name}",
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp",
"appProtocol": "http"
}
],
"essential": true,
"environment": [],
"environmentFiles": [],
"mountPoints": [],
"volumesFrom": [],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-create-group": "true",
"awslogs-group": "/ecs/learn-ecs-task-definition",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs"
}
}
}
]
iam/iam.tf
1行目を下記の内容に修正します。
resource "aws_iam_role" "learn_ecs_task_execution_role" {
name = var.tag_name
-
- assume_role_policy = <<-EOS
- {
- "Version": "2008-10-17",
- "Statement": [
- {
- "Sid": "",
- "Effect": "Allow",
- "Principal": {
- "Service": "ecs-tasks.amazonaws.com"
- },
- "Action": "sts:AssumeRole"
- }
- ]
- }
- EOS
+ assume_role_policy = file("${path.module}/role_policy.json")
}
6行目を下記の内容に修正します。
resource "aws_iam_policy" "learn_ecs_task_execution_role_policy" {
name = var.tag_name
- policy = <<-EOS
- {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": [
- "ecr:GetAuthorizationToken",
- "ecr:BatchCheckLayerAvailability",
- "ecr:GetDownloadUrlForLayer",
- "ecr:BatchGetImage",
- "logs:CreateLogStream",
- "logs:PutLogEvents",
- "logs:CreateLogGroup"
- ],
- "Resource": "*"
- }
- ]
- }
- EOS
+ policy = file("${path.module}/policy_task_execution.json")
}
16行目を下記の内容に修正します。
resource "aws_iam_role" "learn_ecs_task_role" {
name = "${var.tag_name}_task_role"
-
- assume_role_policy = <<-EOS
- {
- "Version": "2008-10-17",
- "Statement": [
- {
- "Sid": "",
- "Effect": "Allow",
- "Principal": {
- "Service": "ecs-tasks.amazonaws.com"
- },
- "Action": "sts:AssumeRole"
- }
- ]
- }
- EOS
+ assume_role_policy = file("${path.module}/role_policy.json")
}
21行目を下記の内容に修正します。
resource "aws_iam_policy" "learn_ecs_task_role_policy_ssmmessages" {
name = "${var.tag_name}_policy_ssmmessages"
- policy = <<-EOS
- {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": [
- "ssmmessages:CreateControlChannel",
- "ssmmessages:CreateDataChannel",
- "ssmmessages:OpenControlChannel",
- "ssmmessages:OpenDataChannel"
- ],
- "Resource": "*"
- }
- ]
- }
- EOS
+ policy = file("${path.module}/policy_ssmmessages.json")
}
iam/role_policy.json
下記の内容で新規作成します。
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
iam/policy_task_execution.json
下記の内容で新規作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:CreateLogGroup"
],
"Resource": "*"
}
]
}
iam/policy_ssmmessages.json
下記の内容で新規作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
}
]
}
ECS環境の構築
下記のコマンドを実行します。
terraform login
Yesで確認し、自動的に開くブラウザウィンドウでワークフローに従います。プロンプトが表示されたら、生成された API キーを Terminal に貼り付ける必要があります。
TerraformCloudで初めてワークスペースを利用する場合は、下記の環境変数を設定する必要があります。
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
詳しくは下記のサイトをご覧ください。
下記のコマンドを実行します。
# プロジェクトの初期化
terraform init
# フォーマット
terraform fmt
# バリデーション
terraform validate
# 作成内容の確認
terraform plan
ここまで特に問題なければ、下記のコマンドを実行します。
# AWSリソースの作成
terraform apply
下記のような出力なっていれば成功です。
Apply complete! Resources: 23 added, 0 changed, 0 destroyed.
Outputs:
lb_dns_name = "xxx.ap-northeast-1.elb.amazonaws.com"
動作確認
上記のOutputで出力されたlb_dns_nameのURLにリクスエストします。リクエストしたコマンドは下記になります。
curl xxx.ap-northeast-1.elb.amazonaws.com
下記のような結果になっていれば動作確認 OK です。
% curl xxx.ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
解説
ecs/ecs.tf
このコード行は、Terraformコード内で、Dockerコンテナの定義を含むJSONテンプレートファイルを使用して、ECSタスク内のコンテナ定義を設定しています。
具体的には、以下のことが行われています:
container_definitions
: ECSタスク内で実行するコンテナの定義を指定しています。このプロパティは、コンテナの配列を含むJSON形式のデータを期待しています。templatefile("${path.module}/learn_ecs_task.json", {...})
:templatefile
関数を使用して、指定されたテンプレートファイルを読み込みます。テンプレートファイルの中には、コンテナ定義の情報を含むためのプレースホルダーが含まれています。{...}
: テンプレートファイル内のプレースホルダーを置換するための値を提供しています。container_name
とrepository_url
という2つの変数を指定しています。これらの変数は、テンプレートファイル内の対応するプレースホルダーに置換されます。
このコードの目的は、learn_ecs_task.json
というテンプレートファイル内にコンテナ定義を記述し、そのテンプレートを元にECSタスクのコンテナ定義を設定することです。具体的なコンテナの設定(コンテナ名、リポジトリURLなど)は、テンプレート内のプレースホルダーを通じて提供されます。
おわりに
今日は、Terraformで構築したECS環境でのjsonファイルの利用についてご紹介しました。
本記事でご紹介したソースは、下記のリポジトリにあります。
https://github.com/Gate-Yossi/Musica/releases/tag/v2023.09.01
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント