我尝试使用Terraform构建ECS环境并启动Laravel网站

首先

我是naritomo。

最近我迷上了使用Terraform进行基础设施开发的编码,同时也对在各个地方广泛使用的GitHub Actions进行持续集成/持续交付感到好奇。因此,我决定首先公开一个能够完成基本搭建的Terraform/Laravel源码。

如果你能给我提供各种建议,我将非常高兴。

项目概述

我正在执行以下事项。 (Wǒ .)

TerraformによるECSインフラ環境構築

Laravelサイトのローカル環境構築/ブランチ更新によるGitHubActionを使用したECS環境への自動デプロイ実施

以下是必要的资源汇总。

 

构成图

构筑的结构如下所示。

使用Terraform(基础设施即代码)在AWS内构建配置图中的基础设施,并使用GitHub Actions 将Laravel网站部署到ECS Fargate。

新規 ビットマップ イメージ.jpg

已确认的操作系统

    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服务删除,因此可以选择不执行。

最后

由于我正在匆忙地创建这个网站,所以如果我自己发现错误或问题,我会进行修正。

如果你有任何困惑的地方或者其他的问题,欢迎给我留下评论,我会感到高兴的。

广告
将在 10 秒后关闭
bannerAds