1. この記事について(6回シリーズ)
この記事は【AWS Fargate】実務的な設計フロー学習シリーズの第5-1弾です。
| 記事 | タイトル | 内容 |
|---|---|---|
| 第1弾 | 設計思考編 | なぜ設計が先なのか |
| 第2弾 | 図解編 | 構成図・フロー図・シーケンス図 |
| 第3弾 | パラメータ設計編 | Terraformパラメータ設計 |
| 第4弾 | Terraform実装編 | コード作成からplan成功まで |
| 第5-1弾 | 実装編 | apply〜アクセス確認 |
| 第5-2弾 | 運用・削除編 | トラブルシューティング〜destroy |
📁 完全なコードはGitHubで公開:GitHub: fargate-iac01
2. はじめに
2-1. この記事の位置づけ
第1弾で学んだ8ステップのうち、この記事では**STEP 8(実装の中盤)**を扱います。
| STEP | 工程 | 記事 | 状態 |
|---|---|---|---|
| 1-7 | グランドデザイン〜IaC設計 | 第1弾〜第3弾 | ✅ 完了 |
| 8(前半) | 実装(コード作成〜plan) | 第4弾 | ✅ 完了 |
| 8(中盤) | 実装(apply〜アクセス確認) | 第5-1弾(この記事) | 📝 今ここ |
| 8(後半) | トラブルシューティング〜destroy | 第5-2弾 | 📋 次回 |
今回のゴール:
- terraform applyでリソースを作成する
- ECRにDockerイメージをpushする
- ブラウザでApacheにアクセスする
2-2. 前回のおさらい
第4弾では、Terraformコードを作成し、terraform plan を成功させました。
| 成果物 | 内容 |
|---|---|
| 10個のTerraformファイル | 合計463行 |
| plan実行結果 | 12個のリソースが作成予定 |
第4弾で確認したこと:
- コードに構文エラーがない
- 作成されるリソースが正しい(VPC、Subnet、ECS等)
- 実行計画が意図通り
次は、実際にterraform applyでリソースを作成します。
2-3. この記事で得られるもの
| 得られること | 説明 |
|---|---|
| ✅ apply実行 | 実際のリソース作成 |
| ✅ ECR操作 | Dockerイメージのpush |
| ✅ アクセス確認 | ブラウザでApacheにアクセス |
2-4. 実装の流れ(3ステップ)
今回は段階的なapplyを使って、エラーを出さずに構築します。
STEP 1: terraform apply -target
↓
ECR Repository作成
↓
STEP 2: docker push
↓
ECRにイメージ配置
↓
STEP 3: terraform apply
↓
VPC/ECS等のリソース作成
↓
✅ Fargateタスク起動成功
| STEP | 作業 | 理由 |
|---|---|---|
| STEP 1 | terraform apply -target(ECRのみ) | ECR Repositoryを先に作成 |
| STEP 2 | docker push | ECRにイメージを配置 |
| STEP 3 | terraform apply(残り全て) | ECS等を作成→タスク起動成功 |
| STEP 4 | アクセス確認 | ブラウザで動作確認 |
| STEP 5 | terraform destroy | リソース削除 |
2-5. なぜこの順番なのか?
2つのパターンを比較してみましょう。
【パターンA: 一度にapply】 【パターンB: 段階的apply(採用)】
━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━
terraform apply ① apply -target ECR
↓ ↓
ECR + ECS同時作成 ② ECR作成のみ
↓ ↓
タスク起動を試みる ③ docker push
↓ ↓
❌ ECRが空なので失敗 ④ イメージ配置完了
↓ ↓
docker push ⑤ terraform apply
↓ ↓
自動リトライ ⑥ VPC/ECS等作成
↓ ↓
✅ タスク起動成功 ⑦ ✅ タスク起動成功
━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━
問題点: 一時的にエラーが出る 利点: 最初からエラーなし
パターンAの問題点:
- ECRとECSが同時に作成される
- ECS ServiceがすぐにFargateタスクを起動しようとする
- ECRにイメージがないためタスク起動失敗(エラーログが出る)
- docker push後、Serviceが自動リトライして成功
- → 初学者が「何かエラーが出た」と混乱する
パターンBのメリット:
- ECRを先に作成してからイメージをpush
- その後ECS等を作成するので、最初から正常にタスクが起動
- エラーが出ないので理解しやすい
-
-targetオプションの使い方も学べる(実務でも使う)
2-6. コラム:docker pushもTerraformでできないの?
できます!ただし...
| 方法 | 説明 | 実務での採用度 |
|---|---|---|
| null_resource | Terraformからシェルコマンド実行 | ⭐⭐ 中 |
| Docker Provider | Terraform公式のDockerプロバイダー | ⭐ 低 |
| CI/CD | GitHub Actions、GitLab CI等 | ⭐⭐⭐⭐⭐ 最高 |
実務のベストプラクティス:
- Terraform: インフラ(ECR、ECS、VPC等)
- CI/CD: アプリケーション(Dockerイメージのビルド・push)
責務分離の理由:
- Terraformはインフラの管理に専念
- Dockerイメージは頻繁に変わるので、CI/CDで管理
- チーム開発で環境差分が出にくい
今回の記事では:
- 学習目的のため、手動でdocker pushを実行
- 実務ではGitHub Actions等のCI/CDツールを使用
3. terraform apply -target(ECRのみ先行作成)
まず、ECR Repositoryだけを先に作成します。
3-1. なぜECRを先に作るのか?
| 理由 | 説明 |
|---|---|
| ✅ イメージの配置が先 | Dockerイメージがないとタスクが起動できない |
| ✅ エラー回避 | 最初からタスクを正常起動させる |
| ✅ 段階的な構築 | 実務でも使うテクニック(-targetオプション) |
3-2. 作業ディレクトリの確認
# 作業ディレクトリに移動
$ cd ~/fargate-terraform
# ファイルが揃っているか確認
$ ls -1
main.tf
vpc.tf
security.tf
ecr.tf
ecs.tf
iam.tf
variables.tf
terraform.tfvars
outputs.tf
.gitignore
# 現在のディレクトリを確認
$ pwd
/home/username/fargate-terraform
重要: 以降、全てのコマンドは ~/fargate-terraform/ で実行します。
3-3. apply前の確認事項
| 確認項目 | 内容 |
|---|---|
| ✅ AWSクレデンシャル |
aws configure が設定済みか |
| ✅ リージョン | terraform.tfvarsのリージョンが正しいか |
| ✅ 既存リソース | 同名のECRリポジトリがないか |
3-4. ECR Repositoryのみ作成
# ECR Repositoryだけを先に作成
fargate-terraform $ terraform apply -target=aws_ecr_repository.main
Terraform will perform the following actions:
# aws_ecr_repository.main will be created
+ resource "aws_ecr_repository" "main" {
+ name = "apache-repo"
+ repository_url = (known after apply)
...
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_ecr_repository.main: Creating...
aws_ecr_repository.main: Creation complete after 1s [id=apache-repo]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
ecr_repository_url = "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/apache-repo"
コマンドの説明:
| 部分 | 説明 |
|---|---|
terraform apply |
リソースを作成 |
-target=aws_ecr_repository.main |
特定のリソースだけを作成 |
aws_ecr_repository.main |
ecr.tfで定義したECR Repository |
ポイント:
-
-targetオプションで一部のリソースだけ作成できる - ECR Repository URLが出力される(次のSTEPで使用)
- 所要時間: 約5秒
3-5. ECR作成の確認
# ECRリポジトリが作成されたか確認
fargate-terraform $ aws ecr describe-repositories --repository-names apache-repo
{
"repositories": [
{
"repositoryArn": "arn:aws:ecr:ap-northeast-1:123456789012:repository/apache-repo",
"registryId": "123456789012",
"repositoryName": "apache-repo",
"repositoryUri": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/apache-repo",
"createdAt": "2024-12-18T10:00:00+09:00",
"imageTagMutability": "MUTABLE"
}
]
}
✅ ECR Repository作成完了!
次のSTEPで、このリポジトリにDockerイメージをpushします。
3-6. コスト目安
| リソース | 料金 |
|---|---|
| Fargate(0.25 vCPU / 0.5 GB) | 約$0.04/時間 |
| VPC、Subnet、IGW、RT | 無料 |
| ECR(1GB未満) | 無料枠内 |
| CloudWatch Logs(5GB未満) | 無料枠内 |
| 合計 | 約$0.04/時間(1時間で約6円) |
4. ECRへDockerイメージpush
apply後、ECSサービスはタスクを起動しようとしますが、ECRにイメージがないため失敗します。
Dockerイメージをpushしましょう。
4-1. terraform outputで必要な情報を確認
まず、terraform outputでECR URLを確認します。
# 出力値を確認
fargate-terraform $ terraform output
ecr_repository_url = "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/apache-repo"
ecs_cluster_name = "fargate-terraform-cluster"
ecs_service_name = "fargate-terraform-service"
ポイント:
-
ecr_repository_url: この値をコピーして以下のコマンドで使用 -
123456789012は自分のAWSアカウントID
4-2. ECRへのログイン
ECRに認証するため、ログインします。
# ECRのログイン情報を取得してDockerにログイン
fargate-terraform $ aws ecr get-login-password --region ap-northeast-1 | \
docker login --username AWS --password-stdin \
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded
コマンドの説明:
| 部分 | 説明 |
|---|---|
aws ecr get-login-password |
ECRのパスワードを取得 |
--region ap-northeast-1 |
リージョンを指定 |
| |
パイプ(前のコマンドの出力を次のコマンドに渡す) |
docker login |
Dockerレジストリにログイン |
--username AWS |
ユーザー名は固定で「AWS」 |
--password-stdin |
パスワードを標準入力から受け取る |
123456789012.dkr... |
ECRのURL(terraform outputで確認した値) |
ポイント:
- パスワードは自動で取得されるので入力不要
- ログインは12時間有効
4-3. Dockerイメージの取得
Docker Hubから公式のApacheイメージを取得します。
# 公式Apacheイメージをpull
fargate-terraform $ docker pull httpd:2.4
2.4: Pulling from library/httpd
a2abf6c4d29d: Pull complete
dcc4698797c8: Pull complete
41c22baa66ec: Pull complete
67283bbdd4a0: Pull complete
d982c879c57e: Pull complete
Digest: sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Status: Downloaded newer image for httpd:2.4
docker.io/library/httpd:2.4
コマンドの説明:
-
docker pull: Docker Hubからイメージをダウンロード -
httpd:2.4: イメージ名とタグ(Apacheの2.4バージョン)
4-4. イメージのタグ付け
ECRにpushするため、イメージにECRのタグを付けます。
# ECR用にタグ付け
fargate-terraform $ docker tag httpd:2.4 \
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/apache-repo:latest
コマンドの説明:
| 部分 | 説明 |
|---|---|
docker tag |
イメージにタグを付ける |
httpd:2.4 |
元のイメージ名 |
123456789012.dkr... |
ECRのURL(terraform outputで確認した値) |
:latest |
タグ名(最新版という意味) |
確認:
# タグ付けされたか確認
fargate-terraform $ docker images | grep apache-repo
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/apache-repo latest xxxxxxxxxxxxx 2 weeks ago 145MB
4-5. ECRへpush
タグ付けしたイメージをECRにアップロードします。
# ECRへpush
fargate-terraform $ docker push \
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/apache-repo:latest
The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/apache-repo]
a2abf6c4d29d: Pushed
dcc4698797c8: Pushed
41c22baa66ec: Pushed
67283bbdd4a0: Pushed
d982c879c57e: Pushed
latest: digest: sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx size: 1234
コマンドの説明:
-
docker push: イメージをECRにアップロード - 各レイヤーが順番にpushされる
- 所要時間: 約30秒〜1分(イメージサイズ約145MB)
4-6. イメージのpush確認
ECRにイメージが正しくアップロードされたか確認します。
# ECRリポジトリのイメージを確認
fargate-terraform $ aws ecr describe-images \
--repository-name apache-repo \
--region ap-northeast-1
{
"imageDetails": [
{
"registryId": "123456789012",
"repositoryName": "apache-repo",
"imageDigest": "sha256:xxxxxxxxxx...",
"imageTags": [
"latest"
],
"imageSizeInBytes": 145123456,
"imagePushedAt": "2024-01-15T12:34:56+09:00"
}
]
}
イメージがpushされた ✅
次のSTEPで、残りのリソース(VPC、ECS等)を作成します。
5. terraform apply(残りのリソース作成)
ECRにイメージを配置したので、残りのリソースを作成します。
5-1. 残りのリソースをapply
# 残りのリソースを全て作成
fargate-terraform $ terraform apply
Terraform will perform the following actions:
# aws_vpc.main will be created
+ resource "aws_vpc" "main" {
+ cidr_block = "10.0.0.0/16"
+ enable_dns_hostnames = true
+ enable_dns_support = true
...
}
# aws_subnet.public will be created
+ resource "aws_subnet" "public" {
+ cidr_block = "10.0.1.0/24"
+ availability_zone = "ap-northeast-1a"
+ map_public_ip_on_launch = true
...
}
# aws_internet_gateway.main will be created
...
# aws_ecs_cluster.main will be created
...
# aws_ecs_task_definition.main will be created
...
# aws_ecs_service.main will be created
...
Plan: 11 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_vpc.main: Creating...
aws_vpc.main: Creation complete after 2s [id=vpc-xxxxxxxxxxxxx]
aws_subnet.public: Creating...
aws_internet_gateway.main: Creating...
...
aws_ecs_service.main: Creating...
aws_ecs_service.main: Creation complete after 10s [id=arn:aws:ecs:...]
Apply complete! Resources: 11 added, 0 to change, 0 destroyed.
Outputs:
ecr_repository_url = "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/apache-repo"
ecs_cluster_name = "fargate-terraform-cluster"
ecs_service_name = "fargate-terraform-service"
ポイント:
- ECR Repositoryは既に作成済みなので、残り11個のリソースを作成
- 所要時間: 約2〜3分
- ECS Serviceが作成されると、自動的にFargateタスクが起動開始
5-2. 作成されたリソースの確認
# VPCの確認
fargate-terraform $ terraform state list | grep aws_vpc
aws_vpc.main
# ECSの確認
fargate-terraform $ terraform state list | grep aws_ecs
aws_ecs_cluster.main
aws_ecs_service.main
aws_ecs_task_definition.main
合計12個のリソースが作成された ✅
5-3. タスクの起動確認
ECS Serviceがタスクを起動したか確認します。
# タスクの状態を確認
fargate-terraform $ aws ecs list-tasks \
--cluster fargate-terraform-cluster \
--service-name fargate-terraform-service \
--region ap-northeast-1
{
"taskArns": [
"arn:aws:ecs:ap-northeast-1:123456789012:task/fargate-terraform-cluster/0123456789abcdef0123456789abcdef"
]
}
✅ タスクが起動成功!
ECRにイメージがあるため、最初から正常にタスクが起動しました。
6. アクセス確認とトラブルシューティング
6-1. タスクARNの取得
# タスクARNを取得
$ TASK_ARN=$(aws ecs list-tasks \
--cluster fargate-terraform-cluster \
--service-name fargate-terraform-service \
--query 'taskArns[0]' \
--output text)
$ echo $TASK_ARN
arn:aws:ecs:ap-northeast-1:123456789012:task/fargate-terraform-cluster/0123456789abcdef0123456789abcdef
6-2. ENI IDの取得
# タスクの詳細からENI IDを取得
$ ENI_ID=$(aws ecs describe-tasks \
--cluster fargate-terraform-cluster \
--tasks $TASK_ARN \
--query 'tasks[0].attachments[0].details[?name==`networkInterfaceId`].value' \
--output text)
$ echo $ENI_ID
eni-0123456789abcdef0
6-3. パブリックIPの取得
# ENIからパブリックIPを取得
$ PUBLIC_IP=$(aws ec2 describe-network-interfaces \
--network-interface-ids $ENI_ID \
--query 'NetworkInterfaces[0].Association.PublicIp' \
--output text)
$ echo $PUBLIC_IP
54.123.45.67
6-4. ブラウザでアクセス
# URLを表示
$ echo "Access: http://$PUBLIC_IP"
Access: http://54.123.45.67
ブラウザで http://54.123.45.67 にアクセスします。
成功画面:
It works!
Apacheのデフォルトページが表示された ✅
6-5. curlで確認
$ curl http://$PUBLIC_IP
<html><body><h1>It works!</h1></body></html>
HTTPレスポンス 200 OK ✅
7. まとめ
7-1. この記事で実現したこと
| 達成項目 | 状態 |
|---|---|
| ✅ ECR Repository作成 | apply -targetで先行作成 |
| ✅ Dockerイメージpush | Apache httpdイメージを配置 |
| ✅ インフラ構築 | VPC、ECS等のリソース作成 |
| ✅ Fargateタスク起動 | コンテナが正常に起動 |
| ✅ アクセス確認 | ブラウザでApache画面表示 |
7-2. 構築された環境
インターネット
↓
Internet Gateway
↓
VPC (10.0.0.0/16)
↓
Public Subnet (10.0.1.0/24)
↓
ECS Fargate (Apache)
←
ECR (httpdイメージ)
リソース数: 12個
所要時間: 約20分
コスト: 約$0.04/時間
7-3. 次の記事へ
次の第5-2弾では、以下を学びます:
| 内容 | 説明 |
|---|---|
| トラブルシューティング | よくある問題と解決方法 |
| リソース確認 | AWSコンソール・CLI・Terraformでの確認 |
| terraform destroy | リソース削除の手順 |
👉 第5-2弾:運用・削除編 へ進む
8. シリーズ一覧
| 記事 | タイトル | 内容 |
|---|---|---|
| 第1弾 | 設計思考編 | なぜ設計が先なのか |
| 第2弾 | 図解編 | 構成図・フロー図・シーケンス図 |
| 第3弾 | パラメータ設計編 | Terraformパラメータ設計 |
| 第4弾 | Terraform実装編 | コード作成からplan成功まで |
| 第5-1弾 | 実装編(この記事) | apply〜アクセス確認 |
| 第5-2弾 | 運用・削除編 | トラブルシューティング〜destroy |