我尝试使用Terraform构建ECS环境并启动Laravel网站
首先
我是naritomo。
最近我迷上了使用Terraform进行基础设施开发的编码,同时也对在各个地方广泛使用的GitHub Actions进行持续集成/持续交付感到好奇。因此,我决定首先公开一个能够完成基本搭建的Terraform/Laravel源码。
如果你能给我提供各种建议,我将非常高兴。
项目概述
我正在执行以下事项。 (Wǒ .)
TerraformによるECSインフラ環境構築
Laravelサイトのローカル環境構築/ブランチ更新によるGitHubActionを使用したECS環境への自動デプロイ実施
以下是必要的资源汇总。
构成图
构筑的结构如下所示。
使用Terraform(基础设施即代码)在AWS内构建配置图中的基础设施,并使用GitHub Actions 将Laravel网站部署到ECS Fargate。

已确认的操作系统
- Windows11(wsl2上のUbuntuから稼働)
参考书籍- Reference materials
使用Terraform搭建Fargate并通过GitHub Actions部署!针对Laravel的编排。
使用Terraform构建Fargate,并通过GitHub Actions进行部署!Laravel版本的同人版。
透過閱讀這本書籍,我的理解有了相當大的進步。
非常感謝。
请参考以下网站
让Ubuntu能够使用AWS CLI
安装Homebrew到Ubuntu上。
【新手向】尝试在Mac上安装Terraform环境。
【Route53】详细说明了如何在AWS上获取自定义域名。
Docker桌面版安装步骤
安装最新版本的Node.js和npm(Ubuntu)
请看这个视频
建立了本网站之后,观看本视频可以更好地理解容器服务的概念。
预先准备工作
请确保已经能够使用以下命令。(请参考相关网站)
git
→githubアカウント準備までできてること。
docker-compose
aws
→awsアカウント設定まで実施していること。
npm
brew
tfenv
在创建AWS帐户后,请使用Route53购买域名。
您还可以在またはお名前ドットコム(或其他外部服务)上购买域名,并将其关联到Route 53。
建设方法(基础设施)
获取资源。
使用以下的git命令获取。
git clone https://github.com/naritomo08/laravel-fargate-infra-public.git laravel-fargate-infra
cd laravel-fargate-infra
rm -rf .git
安装指定版本(1.1.3)的terraform。
tfenv install
域名设置
在Rout53上获取外部域名,并执行以下文件中的域名设置。
vi envs/prod/routing/appfoobar_link/route53.tf
name = "<外向けドメイン名>"を書き換える。
如果您想要使用子域名。
如果想要将 xxx.<外向けドメイン名> 用作外部使用,也需进行以下设置。
在今后的设置中,将执行在xxx.<外向域名>上进行域名设置的操作。
envs/prod/network/routing/appfoobar_link/route53.tf
以下の部分を"xxx.<ドメイン名>"に変更する。
name = data.aws_route53_zone.this.name
envs/prod/network/routing/appfoobar_link/acm.tf
以下の部分を"xxx.<ドメイン名>"に変更する。
domain_name = data.aws_route53_zone.this.name
将S3存储桶名称和DynamoDB表名称更改
需要将以下来自所有资源的S3存储桶名和DynamoDB表名替换掉。
特别是对于S3,需要选择其他人未使用过的名字。
S3:
terraform-state
dynamodb:
terraform_state_lock
基础设施模块建设
请按以下顺序进行构建。
tfstate用S3
cd tfstate
terraform init
terraform plan
terraform apply
ネットワーク周り作成
cd ../envs/prod/network/main
terraform init
terraform plan
terraform apply
ALB用ログ取得S3作成
cd ../../log/alb
terraform init
terraform plan
terraform apply
DBロググループ
cd ../../log/db_foobar
terraform init
terraform plan
terraform apply
Laravelロググループ
cd ../../log/app_foobar
terraform init
terraform plan
terraform apply
SSL証明書/DNSCNAME/ALB作成
cd ../../routing/appfoobar_link
terraform init
terraform plan
terraform apply
*6分かかる
ECR/ECS/.env用S3作成
cd ../../app/foobar
terraform init
terraform plan
terraform apply
AIMユーザ/ポリシー/ecspresso設定作成
cd ../../cicd/app_foobar
terraform init
terraform plan
terraform apply
创建命令说明:
terraform init
*初回構築実行のみ
terraforn plan
*作成前の確認コマンド
*確認失敗が出た場合適宜対応すること。
terraform apply
terraform apply -target <モジュール名>
*作成失敗が出た場合適宜対応すること。
创建关系型数据库(RDS)
cd ../../db/foobar
terraform init
terraform plan
terraform apply
*12分近くかかる。
将DB密码注册到RDS/SystemsManager中。
*DB起動時に実施すること。
aws rds modify-db-instance \
--db-instance-identifier "example-prod-foobar" \
--master-user-password "Passw0rd"
*以下のコマンドは初期構築のみでよい。
aws ssm put-parameter \
--name "/example/prod/foobar/DB_PASSWORD" \
--type "SecureString" \
--value "Passw0rd"
创建Redis
cd ../../cache/foobar
terraform init
terraform plan
terraform apply
*14分近くかかる。
创建Redis/RDS CNAME记录
cd ../../routing/foobar_internal
terraform init
terraform plan
terraform apply
在应用程序中进行构建
继续完成应用程序的构建工作。
构建方法 (应用程序)
获取资源。
在主目录中,可以通过以下的git命令获取。
cd
git clone https://github.com/naritomo08/laravel-fargate-app-public.git laravel-fargate-app
cd laravel-fargate-app
rm -rf .git
启动本地的Docker容器
docker-compose build --no-cache --force-rm
docker-compose up -d
复制.env文件
cd backend
cp .env.example .env
执行Laravel命令
docker-compose exec app composer install -n --prefer-dist --no-dev
docker-compose exec app php artisan key:generate
docker-compose exec app php artisan storage:link
docker-compose exec app chmod -R 777 storage bootstrap/cache
权限设置(在mac上不需要)
cd ..
sudo chown -R $USER:$USER backend
sudo chgrp -R www-data backend/storage backend/bootstrap/cache
sudo chmod -R ug+rwx backend/storage backend/bootstrap/cache
执行npm命令
cd backend
npm ci
npm run prod
进行DB迁移
docker-compose exec app php artisan migrate --force
本地网站确认
将源代码注册到Git
正在GitHub上创建新的代码库。
输入以下命令将源代码注册到GitHub。
请将[name]填写为您的用户名,将[email]填写为您的邮箱地址。
cd ..
git init
git config --local user.name [name]
git config --local user.email [email]
git add .
git commit -m "first commit"
git branch -M main
git remote add origin <作成したリポジトリパス>
git push -u origin main
更新.env.prod文件。
vi backend/.env.prod
ファイル内容
---------------------
APP_URL=https://<外向けドメイン名>
外向けドメイン名を編集すること。
---------------------
部署配置执行。
编辑部署执行文件。
cd .github/workflows
mv deploy.yml.org deploy.yml
vi deploy.yml
修改部分(
run: aws s3 cp .env.$ENV_NAME s3://terraform-state-$SYSTEM_NAME-$ENV_NAME-$SERVICE_NAME-env-file/$IMAGE_TAG/.env
→"terraform-state"のS3バケット名を編集する。
更新部署配置文件。
cd ../../ecspresso
vi config_prod.yml
更正的地方
url: s3://terraform-state/example/prod/cicd/app_foobar_v1.0.0.tfstate
→"terraform-state"のS3バケット名を編集する。
将AWS ID注册到GitHub上
在进行作业之前,将以下数值记录下来。
从AWS IAM用户列表中,为example-prod-foobar-github用户创建新的访问密钥,并记录下访问密钥/密钥访问密码。
进入GitHub仓库页面,点击Settings→secrets→Action,添加以下值。
名前:
PROD_AWS_ACCESS_KEY_ID
→控えたアクセスキーを入れる。
PROD_AWS_SECRET_ACCESS_KEY
→控えたシークレットアクセスキーを入れる。
PROD_AWS_ASSUME_ROLE_ARN
→arn:aws:iam::[AWSアカウントID]:role/example-prod-foobar-deployer
在SystemsManager中注册Laravel APP_KEY
在laravel-fargate-app文件夹中,使用以下命令输入并记录输出结果。
docker-compose up -d
docker-compose exec app php artisan key:generate --show
→出てくるコマンド結果を全て控える
进入AWS Systems Manager,在参数存储中注册以下值。
名前:
/example/prod/foobar/APP_KEY
値:
先程控えた出力結果。
利用的框架是标准。
类型是安全的字符串。
KMS密钥来源设置为当前账户。
KMS密钥ID设置为”alias/aws/ssm”。
通过以下命令也可以进行注册
aws ssm put-parameter \
--name "/example/prod/foobar/APP_KEY" \
--type "SecureString" \
--value "<前の手順で控えた結果>"
执行GitHubAction
进行对主分支的提交/推送,以确保GitHub Action能够正常工作。
可以通过GitHub上相关存储库的”Action”选项卡来查看运行状态。
如果没有要提交的内容,则可以通过以下命令进行操作。
git commit --allow-empty -m "empty commit"
git push
如果失败了,尝试多次重新执行作业,如果在相同的步骤失败,就要检查所构建的步骤是否遗漏了什么。
之后,主分支更新后将自动部署。
确认ECS网站
请参考以下网址。
https://外部域名
一時删除/启动服务的方法(使用基础设施资源实施)
在进行一时削除时,请根据以下项目进行操作;在进行启动时,请从相反的方向进行操作。
为了避免不必要的收费,如果尽量不使用设备,则最好在这个任务中将其删除。
根据情况可以保留RDS/Redis/CNAME记录。
删除/启动ECS服务
服务启动后,由于任务不会自动启动,
您可以通过在应用程序分支上提交/推送到主分支
来启动任务。
从GitHub Action页面上运行最近执行的Action。
cd laravel-fargate-infra/envs/prod/app/foobar
terraform destroy -target aws_ecs_service.this
terraform apply
删除/启动Redis/RDS的CNAME记录。
cd laravel-fargate-infra/envs/prod/routing/foobar_internal
terraform destroy
terraform apply
Redis删除/启动
cd laravel-fargate-infra/envs/prod/cache/foobar
terraform destroy
terraform apply
*14分近くかかる。
删除/启动RDS
cd laravel-fargate-infra/envs/prod/db/foobar
terraform destroy
terraform apply
*12分近くかかる。
将DB密码注册到RDS/SystemsManager。
*RDS起動時に実施すること。
aws rds modify-db-instance \
--db-instance-identifier "example-prod-foobar" \
--master-user-password "Passw0rd"
*以下のコマンドは初期構築のみでよい。
aws ssm put-parameter \
--name "/example/prod/foobar/DB_PASSWORD" \
--type "SecureString" \
--value "Passw0rd"
删除/启动ALB
cd laravel-fargate-infra/envs/prod/routing/appfoobar_link
terraform apply -var='enable_alb=false'
terraform apply
删除国家地址转换(NAT)/ 启动
cd laravel-fargate-infra/envs/prod/network/main
terraform apply -var='enable_nat_gateway=false'
terraform apply
通过将应用程序源代码安装到本环境中来启动ECS (来自其他来源)。
在当前的环境中,我们已确认能够运行Laravel 8。
您可以按照以下步骤启动单独部署的Laravel源代码。
从主源代码创建一个新分支。
将分支名称设置为sitetest。
删除后端文件夹。
sudo rm -rf backend
在后台文件夹执行git clone操作。
git clone <gitソースURL> backend
cd backend
rm -rf .git
创建.env.prod文件。
vi backend/.env.prod
ファイル内容
---------------------
APP_NAME=foobar
APP_ENV=production
# APP_KEY=parameter_store
APP_DEBUG=false
APP_URL=https://<外向けドメイン名>←編集すること。
LOG_CHANNEL=stderr
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=db.foobar.internal
DB_PORT=3306
DB_DATABASE=foobar
DB_USERNAME=foobar
# DB_PASSWORD=parameter_store
SESSION_DRIVER=redis
SESSION_LIFETIME=120
REDIS_HOST=cache.foobar.internal
REDIS_PASSWORD=null
REDIS_PORT=6379
---------------------
创建一个deploy.sh文件。
cd backend
mkdir scripts
vi deploy.sh
ファイル内容
---------------------
#!/bin/bash
set -eu
php artisan config:cache
php-fpm
---------------------
chmod +x deploy.sh
本地重启
docker-compose build --no-cache --force-rm
docker-compose up -d
创建.env文件
cd backend
cp ../.env.example .env
运行Laravel命令
docker-compose exec app composer install -n --prefer-dist --no-dev
docker-compose exec app php artisan key:generate
docker-compose exec app php artisan storage:link
docker-compose exec app chmod -R 777 storage bootstrap/cache
权限设置(在 Mac 上不需要)
sudo chown -R $USER:$USER backend
sudo chgrp -R www-data backend/storage backend/bootstrap/cache
sudo chmod -R ug+rwx backend/storage backend/bootstrap/cache
执行npm命令
cd backend
npm ci
npm run prod
https访问权限
cd backend/app/Http/Middleware
vi TrustProxies.php
protected $proxies;
protected $proxies = "*";
→上記を下記に修正する。
进行DB迁移
docker-compose exec app php artisan migrate --force
在本地验证网站
进行部署配置
cd .github/workflows
vi deploy.yml
更正之处
on:
push:
branches:
- main
- sitetest ←追記する
if: github.ref == 'refs/heads/main'
if: github.ref == 'refs/heads/sitetest'
→2箇所ある上記記載について、上から下に修正する。
执行对”sitetest”的提交/推送后,验证GitHub Action是否正常运行。
确认ECS网站
请参考以下网站。
https://<面向外部的域名>
通过应用程序源代码执行的ECS任务数量更改方法
在标准中,只能启动一个任务,但可以通过以下方法增加任务数量。
cd ecspresso
vi ecs-service-def.json
変更箇所:
"desiredCount": 2,
→"desiredCount"の数字を変更する。
在将任务提交到主分支并更新后,确认 ECS 任务数量是否被更改。
环境清理应用程式
执行部署配置
cd .github/workflows
mv deploy.yml deploy.yml.org
确认执行提交部署后,动作未运行。
执行删除Docker环境的操作。
docker-compose down
删除作业文件夹。
sudo rm -rf laravel-fargate-app
解除在GitHub上的AWS信息注册
进入GitHub存储库页面,点击设置→秘密→Action,然后删除以下数值。
名前:
PROD_AWS_ACCESS_KEY_ID
PROD_AWS_SECRET_ACCESS_KEY
PROD_AWS_ASSUME_ROLE_ARN
在SystemsManager中删除Laravel的APP_KEY和DB_PASS。
进入AWS Systems Manager,并在参数存储中删除以下值。
名前:
/example/prod/foobar/APP_KEY
/example/prod/foobar/DB_PASS
环境清除(基础设施)
删除ECS服务。
cd laravel-fargate-infra/envs/prod/app/foobar
terraform destroy -target aws_ecs_service.this
删除Redis/RDS的CNAME记录。
cd ../../routing/foobar_internal
terraform destroy
terraform state list
删除Redis。
cd ../../cache/foobar
terraform destroy
→6分かかる
terraform state list
删除RDS。
cd ../../db/foobar
terraform destroy
→6分かかる
terraform state list
删除ALB。
cd ../../routing/appfoobar_link
terraform apply -var='enable_alb=false'
删除NAT。
cd ../../network/main
terraform apply -var='enable_nat_gateway=false'
删除用于ECS部署的账号访问密钥
从AWS IAM管理界面中,删除example-prod-foobar-github用户的访问密钥。
删除其他模块(Terraform)。
请按照以下顺序进行删除。
AIMユーザ/ポリシー/ecspresso設定
cd ../../cicd/app_foobar
terraform destroy
terraform state list
Laravelロググループ
cd ../../log/app_foobar
terraform destroy
terraform state list
DBロググループ
cd ../../log/db_foobar
terraform destroy
terraform state list
ECR/ECS/.env用S3
cd ../../app/foobar
terraform destroy
terraform state list
SSL証明書/DNSCNAME/ALB
cd ../../routing/appfoobar_link
terraform destroy
terraform state list
ALB用ログ取得S3
cd ../../log/alb
terraform destroy
terraform state list
ネットワーク周り
cd ../../network/main
terraform destroy
terraform state list
tfstate用S3
cd
cd laravel-fargate-infra/tfstate
terraform destroy
terraform state list
删除命令说明
terraform destroy
terraform destroy -target <モジュール名>
以下のコマンドを入力して、残っているモジュールがないことも確認すること。
terraform state list
リスト確認
結果で残っているモジュールがないか確認できる。
残っているものがある場合"aws_"で始まるモジュールを削除するか、
管理コンソール画面から手動で削除すること。
删除未完全删除的模块。
进入AWS IAM管理页面,删除以下设置。
ロール:
AWSServiceRoleForECS
AWSServiceRoleForElastiCache
AWSServiceRoleForElasticLoadBalancing
AWSServiceRoleForRDS
删除作业文件夹。
sudo rm -rf laravel-fargate-infra
确认付款
放置一天后,确认是否存在任何收费的地方。
从书中的步骤修正部分。
我将在参考书籍内容的基础上进行构建,并记录我遇到的困难部分。
1.5.1 安装Larabel Breeze的命令
docker-compose exec app composer require laravel/breeze:1.10 --dev
1.5.5 进行源代码转译执行
在执行npm系列命令之前,请先执行以下命令在容器中。
在Mac上不需要。
sudo chown -R root:root backend
完成作业后,请输入以下命令以供使用。
sudo chown -R $USER:$USER backend
sudo chgrp -R www-data backend/storage backend/bootstrap/cache
sudo chmod -R ug+rwx backend/storage backend/bootstrap/cache
即使不在容器中执行npm命令,也可以直接在上述权限修订后的后端文件夹内运行”npm run prod”。
如果在登录确认时屏幕出现异常, 请注意
更改Vite的使用场景。
输入以下命令。
sudo rm -f backend/vite.config.js
cd /backend/resource/views/layouts/
sudo vi app.blade.php
sudo vi guest.blade.php
書寫並改寫內容
变更之前
<!-- Scripts -->
@vite(['resources/css/app.css', 'resources/js/app.js'])
更改之后
<!-- Styles -->
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
进行 npm-dev 测试,确认页面是否能够正常显示。
请参考下面的网址
4.16 进行代码转译执行
在 github Action 上,由于某种原因,以下 deploy.yml 文件中的行无法正常工作,因此应将相关命令注释掉。
- run: docker-compose exec -T web npm run prod
另外,需要在以下文件夹中添加”backend/.gitignore”的注释。
/public/css
/public/js
/public/mix-manifest.json
git rm -r --cached .
→コメントアウト後上記コマンドを入力しコミット/プッシュすること。
7.11.2 创建ECS服务
在参考书籍中,保持其原样没有问题,但当使用ecspresso管理ECS任务时,需要进行以下修改,以确保脚本不会自动运行。
vi laravel-fargate-infra/envs/prod/app/foobar/variables.tf
以下の部分を書き換える(1を0にする。)
default = 0
对于ECS服务的健康检查,当前设置的60秒无法及时完成任务,导致任务重新启动以及重复进行部署。为了解决这个问题,建议在初始设置阶段进行以下修正。
vi laravel-fargate-infra/envs/prod/app/foobar/ecs.tf
以下の部分を書き換える(60を3600にする。)
health_check_grace_period_seconds = 3600
通过 GitHub Action 进行 8.6 的部署。
修正以下内容关于部署部分的附加说明。
- name: Download ecspresso
uses: kayac/ecspresso@v1
with:
version: latest
将服务和任务定义从Terraform管理中排除出去。
如果管理不外置,则可能无法执行ECS服务删除,因此可以选择不执行。
最后
由于我正在匆忙地创建这个网站,所以如果我自己发现错误或问题,我会进行修正。
如果你有任何困惑的地方或者其他的问题,欢迎给我留下评论,我会感到高兴的。