前回の記事に続き、第4回は Fargate Deploy を GitHub Actions と連携して行えるようにします。
目次
- 環境構築
- Terraformでインフラ構築.ver1
- Terraformでインフラ構築.ver2
- Terraformでインフラ構築.ver3 ←ココ
- おまけ
4.Terraformでインフラ構築.ver3
このセクションでは以下を行います。
- フロンエンド構築
- Fargate Deploy with GitHubActions
実装範囲はこの辺です。
4-1. フロントエンド構築
これまで、https://subdomain.tfapp.net
に接続すると、laravelのapiを返して画面を表示させていました。
laravelだけのアプリケーションであれば、あとはweb.php
やapi.php
を編集することでlaravelを元にしたアプリケーションを作ることができます。
これ以降の紹介は、laravelをバックエンドAPIとして運用し、フロントエンドは別で管理し運用することを想定した実装を紹介します。
フロントエンド構築
/backend
と同じ階層に/frontend
を構築し、こちらでフロントエンドアプリケーションを管理することにします。
$ cd /workspace/frontend
$ npm create vite@latest .
Need to install the following packages:
create-vite@6.5.0
Ok to proceed? (y) y
> npx
> create-vite .
│
◇ Select a framework:
│ React
│
◇ Select a variant:
│ TypeScript + SWC
│
◇ Scaffolding project in /workspace/frontend...
│
└ Done. Now run:
npm install
npm run dev
portを編集するため、frontend/vite.config.js
を編集します。
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
host: true,
},
});
また、バックエンドと疎通確認するためにApp.tsx
を編集します。
import { useEffect, useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";
function App() {
const [count, setCount] = useState(0);
const [message, setMessage] = useState<string>("");
const [request, setRequest] = useState<{ data: number } | undefined>(
undefined
);
const apiUrl = `${import.meta.env.VITE_BACKEND_API_BASE_URL}/api`;
useEffect(() => {
(async () => {
const data = await fetch(`${apiUrl}/hoge`).then((res) => {
return res.json();
});
setMessage(data.message);
const fuga = await fetch(`${apiUrl}/fuga`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
data: 12345,
}),
}).then((res) => {
return res.json();
});
setRequest(fuga.received);
})();
}, [apiUrl]);
return (
<>
<div>
<a href="https://vite.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>{message}</h1>
<h2>{JSON.stringify(request?.data)}</h2>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
);
}
export default App;
localhost/api
でバックエンドAPIと疎通確認が取れるようにします。
.env.local
と.env.production
をそれぞれ作成し、以下のように修正します。
(viteはnpm run dev
では.env.local
を、npm run prod
では.env.production
をデフォルトで参照します)
VITE_BACKEND_API_BASE_URL=http://localhost
VITE_BACKEND_API_BASE_URL=https://api.tfapp.net
もし、.envがgitignoreの対象外であれば追加してください。
それぞれの.env
はApp.tsx
において、const apiUrl = `${import.meta.env.VITE_BACKEND_API_BASE_URL}/api`;
とすることで、ビルドに応じてバックエンドAPIの参照先を変更しています。
バックエンドAPIの編集
現在、laravelはlocalhost
で表示させています。
localhost/api
でバックエンドAPIとして機能させるように修正します。
<?php
namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
.
.
.// prefix("api")を追加
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->group(base_path('routes/api.php'));
});
}
}
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "api" middleware group. Make something great!
|
*/
Route::get('/hoge', function (Request $request) {
return response()->json(['message' => 'hello world']);
});
Route::post('/fuga', function (Request $request) {
return response()->json(['received' => $request->all(), 'status' => 200]);
});
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => [env('FRONTEND_APP_DOMAIN')],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
laravelでprefix("api")
を追加することで、localhost/api
でリクエストを捌くように修正します。
疎通確認用に、今回はroute.php
にGET
とPOST
を追加しました。
また、初期設定ではオリジンの設定が"*"
なので、'allowed_origins' => [env('FRONTEND_APP_DOMAIN')]
を加えて制限しています。
環境変数FRONTEND_APP_DOMAIN
はあとで、ECRの環境変数にも設定しますが、まずはlaravelの.env
に設定してローカルで疎通確認ができるように修正します。
.
.
.
FRONTEND_APP_DOMAIN=http://localhost:3000
.
.
.
FRONTEND_APP_DOMAIN=
疎通確認
npm run install
とnpm run dev
を実行して、localhost:3000
を表示します。ローカル環境で hello world などバックエンドからのレスポンスが届いているかを確認します。
また、frontendのvite.config.jsでportを3000に修正しましたが、適当にportを変えてオリジンの制御ができているかを確認しておきます。
ここまでで、一度githubのmainにプッシュしておきます。
(Laravelの変更をgithubActionsでコンテナに、フロントエンドはAmplifyに適用)
AWS Amplifyでデプロイ
今回は簡略化して、AWS Amplifyを使ってフロントエンドアプリをデプロイすることにします。
作成にあたってGitHubとのOAuth認証許可が必要になります。
認証許可と作成したリポジトリを指定し、yamlを以下のように修正します。
version: 1
frontend:
phases:
preBuild:
commands:
- cd frontend
- npm install
build:
commands:
- npm run build
artifacts:
baseDirectory: frontend/dist
files:
- "**/*"
cache:
paths:
- frontend/node_modules/**/*
laravelもあとで修正するので、一旦バックエンドAPIとして以下を設定します。
Key: VITE_BACKEND_API_BASE_URL
Value: https://api.tfapp.net
設定後、デプロイを実行し、払い出されたURLにアクセスしてフロントエンドアプリが表示できるか確認します。
サブドメインの設定
フロントエンドアプリは例としてサブドメインをfrontend
と設定します。
以降はアプリケーションの構造として、
フロントエンド:frontend.tfapp.net
バックエンド:api.tfapp.net
とします。
ドメインを追加
を選択し、フロントエンドアプリケーションにfrontend
を設定し、カスタムドメインを設定してください。設定完了後、数分経てば設定したドメインからアプリを確認できます。
Laravelを再定義
現在Laravelはsubdomain.tfapp.net
でアプリが公開されています。
本番環境ではフロントエンドのドメインを参照する必要があるので、SSMで設定します。
そのあと、Laravelアプリを再デプロイして、本番環境で疎通確認が取れるかを確認します。
SSMでフロントエンドドメインを設定
マネコンから以下の値を設定します。
キー:/test/prod/tfapp/FRONTEND_APP_DOMAIN
タイプ:安全な文字列
値:https://frontend.tfapp.net
Nginxのcontainer.confを編集します。
.
.
.
server {
server_name api.tfapp.net; # subdomain.tfapp.net → api.tfapp.netに変更
sendfile on;
ecs.tfのコンテナタスクを以下のように修正します。
具体的には各コンテナのimage参照方法とsecrets(FRONTEND_APP_DOMAIN)を1つ追加します。
resource "aws_ecs_task_definition" "this" {
.
.
.
container_definitions = jsonencode(
[
{
name = "nginx"
// 編集
image = "${module.nginx.ecr_repository_this_repository_url}@${data.aws_ecr_image.nginx_latest.image_digest}"
portMappings = [
{
containerPort = 80
protocol = "tcp"
}
]
environment = []
secrets = []
dependsOn = [
{
containerName = "php"
condition = "START"
}
]
mountPoints = [
{
containerPath = "/var/run/php-fpm"
sourceVolume = "php-fpm-socket"
}
]
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = "/ecs/${local.name_prefix}-${local.service_name}/nginx"
awslogs-region = data.aws_region.current.id
awslogs-stream-prefix = "ecs"
}
}
},
{
name = "php"
// 編集
image = "${module.php.ecr_repository_this_repository_url}@${data.aws_ecr_image.php_latest.image_digest}"
portMappings = []
environment = []
secrets = [
{
name = "APP_KEY"
valueFrom = "/${local.system_name}/${local.env_name}/${local.service_name}/APP_KEY"
},
// 追加
{
name = "FRONTEND_APP_DOMAIN"
valueFrom = "/${local.system_name}/${local.env_name}/${local.service_name}/FRONTEND_APP_DOMAIN"
}
]
mountPoints = [
{
containerPath = "/var/run/php-fpm"
sourceVolume = "php-fpm-socket"
}
]
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = "/ecs/${local.name_prefix}-${local.service_name}/php"
awslogs-region = data.aws_region.current.id
awslogs-stream-prefix = "ecs"
}
}
}
]
)
.
.
.
}
resource "aws_ecs_service" "this" {
.
.
.
enable_execute_command = true
force_new_deployment = true // 追加
}
/app
以下でmoduleの参照を追加します。
data "aws_ecr_image" "nginx_latest" {
repository_name = module.nginx.ecr_repository_this_name
image_tag = "latest"
}
data "aws_ecr_image" "php_latest" {
repository_name = module.php.ecr_repository_this_name
image_tag = "latest"
}
modules/ecr/outputs.tf
に以下を追加します。
output "ecr_repository_this_name" {
value = aws_ecr_repository.this.name
}
バックエンドAPIのサブドメインを変更
これまでLaravelアプリをsubdomain.tfapp.net
としましたが、バックエンドAPIとしてアプリを変更するため、サブドメインをapi
とすることにします。
こちらのサブドメインはterraform上で管理しているため、該当箇所を修正します。
resource "aws_route53_record" "alb_record" {
count = var.enable_alb ? 1 : 0
zone_id = data.aws_route53_zone.this.zone_id
name = "api" // subdomain -> api に変更
type = "A"
alias {
name = aws_lb.this[0].dns_name
zone_id = aws_lb.this[0].zone_id
evaluate_target_health = true
}
}
修正が完了したら、それぞれの機構でapplyします。
ALB
$ cd envs/prod/routing/tfapp_net
$ terraform apply
NATゲートウェイ
$ cd envs/prod/network/main
$ terraform apply
ECS
$ cd envs/prod/app/
$ terraform apply
タスクがRUNするまで少々時間がかかりますが、Amplifyで設定したfrontend.tfapp.net
に接続後、バックエンドAPIと疎通確認が取れており、localhostで立ち上げた時のように表示できていればOKです。
確認後、余計な課金を防ぐのであれば、以下のコマンドを各ディレクトリで実行してリソースの稼働を切っておきます。
ALB
$ cd envs/prod/routing/tfapp_net
$ terraform apply -var="enable_alb=false"
NATゲートウェイ
$ cd envs/prod/network/main
$ terraform apply -var='enable_nat_gateway=false'
ECRタスク
$ cd envs/prod/app
$ terraform apply -var="desired_count=0"
4-2. GitHub ActionsでFargateデプロイ
ecspressoの導入
ecspresso は ECS のサービス定義とタスク定義を管理することにフォーカスしたツールです。
デプロイのたびに更新の必要があるリソース(ECSサービスとタスク定義などのアプリケーション管理側)はecspressoで管理し、それ以外のインフラの管理を Terraform に分けることができます。
これを導入することで、GithubActionsのワークフロー上でコンテナをECR登録した後、ecspressoを実行してECSを自動でデプロイさせることができます。
ecspressoをローカルにインストールし、トップレベルにecspressoディレクトリを作成、配下にいくつかの定義ファイルを作成します。
以下のDockerfileに追記されていなければ追記します。
# AWS CLI v2 install
RUN curl -sS "https://awscli.amazonaws.com/awscli-exe-linux-$(uname -m).zip" -o "awscliv2.zip" \
&& unzip awscliv2.zip \
&& ./aws/install \
&& rm -rf aws awscliv2.zip
.
.
. 追加していなければ追記
# ecspresso instakk
RUN curl -Lo ecspresso.tar.gz "https://github.com/kayac/ecspresso/releases/download/v2.5.0/ecspresso_2.5.0_linux_amd64.tar.gz" \
&& tar -xzf ecspresso.tar.gz \
&& chmod +x ecspresso \
&& mv ecspresso /usr/local/bin/ \
&& rm ecspresso.tar.gz
追加した後はコンテナをリビルドします。
リビルト後はインストールできたか確認します。
$ ecspresso version
ecspresso v2.5.0
ecspressoのセットアップを行います。
/terraformと同階層にecspressoディレクトリを作成します。
その後、設定したクラスター名・サービス名を指定してconfigファイルを作成します。
ecspressoの挙動
内部的には、ecspresso init
を行うことで、指定された cluster と service に対して AWS API を叩いて現在の ECS の構成を取得している。
その情報を基に以下の定義ファイルを作成している。
$ mkdir ecspresso
$ cd ecspresso
$ ecspresso init --config config.yaml --region ap-northeast-1 --cluster test-prod-tfapp --service test-prod-tfapp
各種ファイルが生成できれば、ecspressoによる手動デプロイを試します。
dry run
ecspressoでデプロイするときに、以下のように--dry-runオプションを付けることで、実際にはデプロイせずに、デプロイの事前検証ができます。実行後にDRY RUN OK
と出ればOKです。
$ ecspresso deploy --config config.yaml --dry-run
2025-06-24T13:38:37.390+09:00 [INFO] [test-prod-tfapp/test-prod-tfapp] service attributes will not change
2025-06-24T13:38:37.390+09:00 [INFO] [test-prod-tfapp/test-prod-tfapp] desired count: 0
2025-06-24T13:38:37.390+09:00 [INFO] [test-prod-tfapp/test-prod-tfapp] DRY RUN OK
ecspressoによるデプロイ
実際にecspressoでデプロイするには以下のコマンドを叩きます。
Completed!
となればデプロイ成功です。
(ロードバランサー / NATゲートウェイが有効であること)
$ ecspresso deploy --config config.yaml
ブラウザでアプリケーションにアクセスして問題なくECSタスクが起動していればOKです。
ECSタスクを止める
--tasks 0
を付与することで、すべてのECSタスクが停止できます。
Completed!
となれば停止成功です。
$ ecspresso deploy --config config.yaml --tasks 0
tfstate共有とデプロイ環境対応
設定したtfstateを直接参照できるように設定します。
ecspressoは参照できるtfstateが1つしかできないので、ecspresso用のterraformファイルを作成します。
実装のイメージとしては、
- ecspresso用にtfファイルを作成 & 参照設定
- githubActionsからecspressoを叩けるようにiam_policyを追加
- workflow/deploy.yaml修正
- espresso/以下のconfigファイル修正
で行います。
まずは 「ecspresso用にtfファイルを作成 & 参照設定」 を行います。
以下のディレクトリにファイルを作成します。
data "aws_ecr_repository" "nginx" {
name = "${local.name_prefix}-${local.service_name}-nginx"
}
data "aws_ecr_repository" "php" {
name = "${local.name_prefix}-${local.service_name}-php"
}
data "aws_iam_role" "ecs_task_execution" {
name = "${local.name_prefix}-${local.service_name}-ecs-task-execution"
}
data "aws_iam_role" "ecs_task" {
name = "${local.name_prefix}-${local.service_name}-ecs-task"
}
data "aws_lb_target_group" "this" {
name = "${local.name_prefix}-${local.service_name}"
}
data "aws_security_group" "vpc" {
name = "${local.name_prefix}-main-vpc"
}
data "aws_subnet" "private" {
for_each = var.azs
tags = {
Name = "${local.name_prefix}-main-private-${each.key}"
}
}
variable "azs" {
type = map(object({
public_cidr = string
private_cidr = string
}))
default = {
a = {
public_cidr = "172.31.0.0/20"
private_cidr = "172.31.48.0/20"
},
c = {
public_cidr = "172.31.16.0/20"
private_cidr = "172.31.64.0/20"
}
}
}
data "aws_cloudwatch_log_group" "nginx" {
name = "/ecs/${local.name_prefix}-${local.service_name}/nginx"
}
data "aws_cloudwatch_log_group" "php" {
name = "/ecs/${local.name_prefix}-${local.service_name}/php"
}
data "aws_ecs_service" "this" {
cluster_arn = "${local.name_prefix}-${local.service_name}"
service_name = "${local.name_prefix}-${local.service_name}"
}
追加したtfstate(S3)をecspressoから読み込めるようにiam.tf
を編集します。
.
.
.
# ecspresso s3読取権限
resource "aws_iam_role_policy" "s3" {
name = "s3"
role = aws_iam_role.deployer.id
policy = jsonencode(
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::tfapp-tfstate/${local.system_name}/${local.env_name}/cicd/app/${local.service_name}_*.tfstate"
}
]
}
)
}
# ecspresso ecsデプロイ権限
resource "aws_iam_role_policy" "ecs" {
name = "ecs"
role = aws_iam_role.deployer.id
policy = jsonencode(
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RegisterTaskDefinition",
"Effect": "Allow",
"Action": [
"ecs:RegisterTaskDefinition",
"ecs:TagResource"
],
"Resource": "*"
},
{
"Sid": "PassRoleInTaskDefinition",
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": [
data.aws_iam_role.ecs_task.arn,
data.aws_iam_role.ecs_task_execution.arn
]
},
{
"Sid": "DeployService",
"Effect": "Allow",
"Action": [
"ecs:UpdateService",
"ecs:DescribeServices",
],
"Resource": [
data.aws_ecs_service.this.arn
]
}
]
}
)
}
作成後、apply
を実行しecspressoでtfstateを読み込めるようにします。
$ cd /envs/prod/cicd/app
$ terraform apply
workflow/deploy.yamlを修正します。
コンテナをECRにプッシュした後、ecspressoをセットアップ→ECSにデプロイするステップを追加します。
.
.
. 以下追記
- name: Set up ecspresso
uses: kayac/ecspresso@v0
with:
version: v2.5.0
- name: Deploy to ECS
run: ecspresso deploy --config config_$ENV_NAME.yaml
working-directory: ./ecspresso
run: ecspresso deploy --config config_$ENV_NAME.yaml
にもあるように、各環境によって、configの参照を変えるようにしています。そのため、ecspresso init
をしたときに作成された、config.yaml
をconfig_prod.yaml
にリネームした上で以下の編集を続けます。
ecspressoから実行したtfstateを読み込みめるようにplugin
をconfig.yamlに追記します。
.
.
.
timeout: "10m0s"
image_digest: true // 追記
plugins: // 追記
- name: tfstate
config:
url: s3://tfapp-tfstate/test/prod/cicd/app/tfapp_v1.5.0.tfstate
/ecspressoのjsonをそれぞれ修正します。
{
"availabilityZoneRebalancing": "DISABLED",
"capacityProviderStrategy": [
{
"base": 0,
"capacityProvider": "FARGATE_SPOT",
"weight": 1
}
],
"deploymentConfiguration": {
"deploymentCircuitBreaker": {
"enable": false,
"rollback": false
},
"maximumPercent": 200,
"minimumHealthyPercent": 100
},
"deploymentController": {
"type": "ECS"
},
"desiredCount": 1,
"enableECSManagedTags": false,
"enableExecuteCommand": true,
"healthCheckGracePeriodSeconds": 60,
"launchType": "",
"loadBalancers": [
{
"containerName": "nginx",
"containerPort": 80,
"targetGroupArn": "{{ tfstate `data.aws_lb_target_group.this.arn` }}"
}
],
"networkConfiguration": {
"awsvpcConfiguration": {
"assignPublicIp": "DISABLED",
"securityGroups": [
"{{ tfstate `data.aws_security_group.vpc.id` }}"
],
"subnets": [
"{{ tfstate `data.aws_subnet.private['a'].id` }}",
"{{ tfstate `data.aws_subnet.private['c'].id` }}"
]
}
},
"platformFamily": "Linux",
"platformVersion": "1.4.0",
"propagateTags": "NONE",
"schedulingStrategy": "REPLICA",
"tags": [
{
"key": "Env",
"value": "{{ must_env `ENV_NAME` }}"
},
{
"key": "System",
"value": "{{ must_env `SYSTEM_NAME` }}"
},
{
"key": "Name",
"value": "{{ must_env `SYSTEM_NAME` }}-{{ must_env `ENV_NAME` }}-{{ must_env `SERVICE_NAME` }}"
}
]
}
{
"containerDefinitions": [
{
"cpu": 0,
"dependsOn": [
{
"condition": "START",
"containerName": "php"
}
],
"essential": true,
"image": "{{ tfstate `data.aws_ecr_repository.nginx.repository_url` }}:{{ must_env `IMAGE_TAG` }}",
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "{{ tfstate `data.aws_cloudwatch_log_group.nginx.name` }}",
"awslogs-region": "{{ must_env `AWS_REGION` }}",
"awslogs-stream-prefix": "ecs"
}
},
"mountPoints": [
{
"containerPath": "/var/run/php-fpm",
"sourceVolume": "php-fpm-socket"
}
],
"name": "nginx",
"portMappings": [
{
"appProtocol": "",
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}
],
"versionConsistency": ""
},
{
"cpu": 0,
"essential": true,
"image": "{{ tfstate `data.aws_ecr_repository.php.repository_url` }}:{{ must_env `IMAGE_TAG` }}",
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "{{ tfstate `data.aws_cloudwatch_log_group.php.name` }}",
"awslogs-region": "{{ must_env `AWS_REGION` }}",
"awslogs-stream-prefix": "ecs"
}
},
"mountPoints": [
{
"containerPath": "/var/run/php-fpm",
"sourceVolume": "php-fpm-socket"
}
],
"name": "php",
"secrets": [
{
"name": "APP_KEY",
"valueFrom": "/{{ must_env `SYSTEM_NAME` }}/{{ must_env `ENV_NAME` }}/{{ must_env `SERVICE_NAME` }}/APP_KEY"
},
{
"name": "FRONTEND_APP_DOMAIN",
"valueFrom": "/{{ must_env `SYSTEM_NAME` }}/{{ must_env `ENV_NAME` }}/{{ must_env `SERVICE_NAME` }}/FRONTEND_APP_DOMAIN"
}
],
"versionConsistency": ""
}
],
"cpu": "256",
"executionRoleArn": "{{ tfstate `data.aws_iam_role.ecs_task_execution.arn` }}",
"family": "{{ must_env `SYSTEM_NAME` }}-{{ must_env `ENV_NAME` }}-{{ must_env `SERVICE_NAME` }}",
"ipcMode": "",
"memory": "512",
"networkMode": "awsvpc",
"pidMode": "",
"requiresCompatibilities": [
"FARGATE"
],
"tags": [
{
"key": "Env",
"value": "{{ must_env `ENV_NAME` }}"
},
{
"key": "System",
"value": "{{ must_env `SYSTEM_NAME` }}"
},
{
"key": "Name",
"value": "{{ must_env `SYSTEM_NAME` }}-{{ must_env `ENV_NAME` }}-{{ must_env `SERVICE_NAME` }}"
}
],
"taskRoleArn": "{{ tfstate `data.aws_iam_role.ecs_task.arn` }}",
"volumes": [
{
"host": {},
"name": "php-fpm-socket"
}
]
}
ここまで設定した後はmain
ブランチにコードをプッシュすると自動でECR登録→ECSデプロイが実行されます。
なお、/ecspresso以下のファイルはtfstateやENV_NAMEなど注入された値を参照するように編集しているため、ローカルでECSデプロイを行う場合は
# 起動
$ IMAGE_TAG=latest AWS_REGION=ap-northeast-1 \
SYSTEM_NAME=test ENV_NAME=prod SERVICE_NAME=tfapp \
ecspresso deploy --config=config_prod.yaml --skip-task-definition
# 停止
$ IMAGE_TAG=latest AWS_REGION=ap-northeast-1 \
SYSTEM_NAME=test ENV_NAME=prod SERVICE_NAME=tfapp \
ecspresso deploy --config=config_prod.yaml --skip-task-definition --tasks 0
のように環境変数などを指定する必要があります。
次回
ここまでで4.Terraformでインフラ構築.ver3が終了しました。
1~4回までで一通りWebアプリケーション実装ができました。
次回おまけセクションでは、MFA設定とSwitchRole設定を紹介できればと思います。
他の記事