GitHub Actionsでデプロイ Laravel編Terraform備忘録

GitHub Actionsでデプロイ Laravel編Terraform備忘録

概要
基礎習得復習

1章 Laravelアプリケーションの作成

最終的な構成図

出典1:(BOOTHのサンプル)TerraformでFargateを構築してGitHub Actionsでデプロイ! …
出典2:(Amazon) TerraformでFargateを構築してGitHub Actionsでデプロイ!Laravel編 (技術の泉シリーズ(NextPublishing)) Kindle版
コマンド集

// Laravel Breezeをインストール
laravel-fargate-app2 % docker-compose exec app composer  require laravel/breeze "1.*" --dev
laravel-fargate-app2 % docker-compose exec app  php artisan breeze:install   
laravel-fargate-app2 % docker-compose exec web npm install
laravel-fargate-app2 % docker-compose exec web npm run dev

2章 Terraformのセットアップ

// AWS CLIコマンドでIAMユーザ一覧を取得する(動作確認用)
laravel-fargate-app2 % aws iam list-users --profile  yukio.takakura.admin

3章 ECRの構築とTerraformの基本操作

構成

terraform コード
https://github.com/yukiotakakura/laravel-fargate-infra2/pull/1/files

マネコン

考慮事項候補

・ECRRepositoryには、何個Docker imageを保管するか
・xxxx

コマンド集

// ディレクトリ配下にあるtfファイルを整形する 
prod % terraform fmt --recursive
【結果】
app/foobar/backend.tf


// シンボリックリンクの作成
foobar % ln -fs ../../provider.tf provider.tf
foobar % ln -fs ../../shared_locals.tf shared_locals.tf 

//  プロファイルをエクスポートする
foobar % export AWS_PROFILE="yukio.takakura.admin"  

// モジュールを追加するたびに実行する
foobar % terraform init
foobar % terraform plan
foobar % terraform apply

4章 GitHub ActionsでDockerイメージをECRにプッシュする

構成

ソースコード
・GitHubがACLコマンドでECRにログインしてECRにイメージをpushするまでのワークフローを構築
4章 GitHub ActionsでDockerイメージをECRにプッシュする

terraform コード
・GitHub専用のIAMユーザーとIAMロールを作成
4章 GitHub ActionsでDockerイメージをECRにプッシュする

考慮事項候補

・IAMロールの権限は必要最低限とすること
・xxxx

マネコン

コマンド集

main % terraform apply -var='enable_nat_gateway=false'

第5章 ネットワーク(VPC)の構築

構成

詳細

terraform コード
・VPC作成
・IGW作成
・サブネット作成
・ルートテーブル作成
・NATゲートウェイ作成
・セキュリティグループ作成
https://github.com/yukiotakakura/laravel-fargate-infra2/pull/4

考慮事項候補

・xxxx
・xxxx

6章 ドメインの取得とロードバランサーの構築

構成

詳細

terraform コード
・Route53 ホストゾーン作成
・ACMでドメインの証明書発行
・ALB(ALB、リスナー、リスナールール、ターゲットグループ)作成
・ALBのログを保管するためのS3バケット作成
・Route53 ホストゾーンにレコードを登録

https://github.com/yukiotakakura/laravel-fargate-infra2/pull/5

考慮事項候補

・ALBのログ収集期間、ログ保存期間、S3のクラス、ライフサイクル
・xxxx

動作確認

7章 ECS(Fargate)の構築

構成図

詳細
1つタスクの中に、php-fpmコンテナとNginxコンテナが存在している

terraform コード

https://github.com/yukiotakakura/laravel-fargate-infra2/pull/6

考慮事項

・機密情報系、DBのid、パスワード等はTerraformの管理外とすること
・プライベートサブネットのECS Exec、、、、

コマンド集

// 現在起動中であるECSタスクIDを取得する
// ▼構文
aws ecs list-tasks \
  --cluster {ECSクラスタ名} \
  --service-name {ECSサービス名} \
  --region {リージョン名} \
  --profile {プロファイル名}


// ▼具体例
aws ecs list-tasks \
  --cluster example-prod-foobar \
  --service-name example-prod-foobar \
  --region ap-northeast-1 \
  --profile yukio.takakura.admin


【結果】
 
{
    "taskArns": [
        "arn:aws:ecs:ap-northeast-1:xxxxx:task/example-prod-foobar/{タスクID}"
    ]
}


// ECSタスクにログインする
// ▼構文
aws ecs execute-command \
  --region {リージョン名} \
  --cluster {ECSクラスタ名} \
  --container {コンテナ名} \
  --interactive \
  --command "/bin/sh" \
  --task {タスクID} \
  --profile {プロファイル名}


// ▼具体例
aws ecs execute-command \
  --region ap-northeast-1 \
  --cluster example-prod-foobar \
  --container php \
  --interactive \
  --command "/bin/sh" \
  --task {タスクID} \
  --profile yukio.takakura.admin

【結果】
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.

8章 ecspressoのセットアップ

terraform コード
https://github.com/yukiotakakura/laravel-fargate-infra2/pulls

コマンド集

-------------------------------------------------------------
ecspressoコマンド
-------------------------------------------------------------
laravel-fargate-app2 % ecspresso version
laravel-fargate-app2 % ecspresso init --config config.yaml --region ap-northeast-1 --cluster example-prod-foobar --service example-prod-foobar

// デプロイの事前検証コマンド
% ecspresso deploy --config config.yaml --dry-run
// デプロイコマンド
% ecspresso deploy --config config.yaml
【結果】
2024/05/01 19:55:22 example-prod-foobar/example-prod-foobar Service is stable now. Completed!


// ECSタスクを停止するコマンド
ecspresso deploy --config config.yaml --tasks 0

-------------------------------------------------------------
terraformコマンド
-------------------------------------------------------------
// 
% terraform state rm aws_ecs_service.this

% terraform state rm aws_ecs_task_definition.this

9章 Laravelとnginxを本番環境向けに修正する

設定系

TrustProxies.php

①、②両方ある。MVCアーキテクチャーの場合はTrustProxies.php設定必要
①TrustProxies.phpの設定が必要なケース
②TrustProxies.phpの設定が不要なケース

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array<int, string>|string|null
     */
    protected $proxies = '*';

    /**
     * The headers that should be used to detect proxies.
     *
     * @var int
     */
    protected $headers =
        Request::HEADER_X_FORWARDED_FOR |
        Request::HEADER_X_FORWARDED_HOST |
        Request::HEADER_X_FORWARDED_PORT |
        Request::HEADER_X_FORWARDED_PROTO |
        Request::HEADER_X_FORWARDED_AWS_ELB;
}
Laravelのログ

LaravelのログをCloudWatch Logsに連携する。

Laravelデフォルトでは例外が発生したなどなど諸々laravel.logファイルにエラーが出力される。


Laravelのエラー内容をCloudWatch連携するには下記設定を行う
■前提条件
・CloudWatchロググループが作成済みである
・ECSのタスクからCloudWatchに対する書き込み権限(AWS側ポリシー)があること
・ECSのタスク定義書のlogConfigurationが作成済みCloudWatchロググループと紐づいていること

最終的にはアプリの.envを下記のように設定する

LOG_CHANNEL=stderr
LOG_LEVEL=info

.envファイルの置き場所

none

nginx関連
不要なログは吐かないように調整する

不要なログを出力してしまうとログを調査する場面でノイズが多くなる為、不要なログは吐かない方が良い
ログを調査する具体場面
・アクセス解析をしたいとき
・障害発生後に影響調査を調査したいとき
・処理速度を調査したいとき
・etc,,,,

不要ログを除外_ALBのヘルスチェック
http {
    // $http_user_agentに「ELB-HealthChecker」となっている場合は、$loggableを0とする
    map $http_user_agent $loggable {
        ~ELB-HealthChecker  0;
        default             1;
    }

    // $loggableが1の場合、ログ出力する
    access_log  /var/log/nginx/access.log  main if=$loggable;
}


逆にALBのヘルスチェックを含めてしまうと、下記キャプチャのようにELB-HealthCheckerログが大量出力されてしまう

不要ログを除外_静的ファイルへのアクセス&&フロントエンドの404エラー
server {
    listen 80;
    root /work/backend/public;

    // 拡張子がcss|gif|ico|jpeg|jpg|js|pdf|png|svg|txt|zipの場合
    location ~ \.(css|gif|ico|jpeg|jpg|js|pdf|png|svg|txt|zip) {
        expires 30d;
        access_log off;
        log_not_found off;
    }

}


access_log
locationの中で指定したファイル群をアクセスログに出力しない

log_not_found_off
locationの中で指定したファイル群を404 Not Foundエラーログを出力しない
フロントエンドの404エラーは不要

expires
クライアントのキャッシュ有効期限を30日とする。キャッシュするための1つの手段。

逆に上記を設定しないと、ALBのログにcss、imageといった静的ファイルのアクセスログが大量出力されてしまったり、(推測)画像のリンク切れの404エラーが大量出力されてしまう

パフォーマンス向上系
http {
    sendfile        on;
    tcp_nopush      on;


    gzip  on;
    gzip_types text/css application/javascript application/json;
}

tcp_nopush

onにすると、レスポンスヘッダとファイルの先頭をひとつのパケットで効率よく送るようになります。なお、sendfileもonである必要があります。

■他参考記事
nginxのパラメータチューニングとh2o


gzip/ gzip_types

gzipをonにすると、コンテンツを圧縮して転送します。
gzip_typesでは、圧縮するコンテンツの種類をMIMEタイプを使って指定します。
なお、text/htmlは常に圧縮されるため、指定は不要です

ログのフォーマット

ログフォーマットを変更しないと、ログの先頭がALBのIP固定となってしまって、わかづらい。
本来は、クライアントのIPを先頭に表示したい


ELB経由のnginxでアクセス元IPアドレスをアクセスログの$remote_addrとして書くようにする

server {
    set_real_ip_from  172.31.0.0/16; // ★環境変数化すること
    real_ip_header    X-Forwarded-For;
    real_ip_recursive on;

}

コマンド集

// 権限確認 
laravel-fargate-app2 % ls -l backend/scripts/deploy.sh 
【結果】
-rw-r--r--  1 yukio  staff  56 May  2 12:36 backend/scripts/deploy.sh

// shファイルの実行権限を追加する
laravel-fargate-app2 % chmod +x backend/scripts/deploy.sh

// 権限確認
【結果】 
-rwxr-xr-x  1 yukio  staff  56 May  2 12:36 backend/scripts/deploy.sh

-------------------------------------------------------------
ecspressoコマンド
-------------------------------------------------------------
// 認証情報を開放
ecspresso % export AWS_PROFILE="yukio.takakura.admin"
// デプロイ検証
ecspresso % ecspresso deploy --config config_prod.yaml   --dry-run
// デプロイ実施
ecspresso % ecspresso deploy --config config_prod.yaml

10章 RDSとプライベートホストゾーンの構築

構成図

詳細

terraform コード
ネットワーク
・RDS用のセキュリティグループを作成
・RDS用サブネットグループ作成
RDSインスタンス
・パラメーターグループ定義
・オプショングループ定義
・一般ログ、スロークエリ、エラーログのCloudWatch有効化
・RDSインスタンス作成
その他
・名前解決(RDSエンドポイント⇔ドメイン化)
・パラメーターストア

https://github.com/yukiotakakura/laravel-fargate-infra2/pull/8

考慮事項

構築
・RDSクラスター化すること
・同期方法(同期、非同期、準同期)の選定
運用
・ログ(スロークエリ、etc,,)
・バックアップ手法の確率
・障害が起きた場合の復旧

コマンド集

// AWS CLI 特定RDSインスタンスのパスワードを変更する
% aws rds modify-db-instance \
 --db-instance-identifier "example-prod-foobar" \
 --master-user-password "{入力パスワード}" \
 --profile yukio.takakura.admin

// パラメーターストアにRDSパスワードとして環境変数を定義
% aws ssm put-parameter \
 --name "/example/prod/foobar/DB_PASSWORD" \
 --type "SecureString" \
 --value "パスワード" \
 --profile yukio.takakura.admin


// 
$VPC_CIDR={VPC_ID} IMAGE_TAG=latest AWS_REGION=ap-northeast-1 \
SYSTEM_NAME=example ENV_NAME=prod SERVICE_NAME=foobar \
ecspresso deploy --config=config_prod.yaml --skip-task-definition

11章 ElastiCache(Redis)の構築

構成図

詳細

terraform コード
・ElastiCache用セキュリティグループ 作成
・ElastiCache用サブネットグループ作成
・ElastiCache用パラメーターグループ作成
・ElastiCache レプリケーショングループ作成
・ElastiCache用のCNAMEレコード作成
https://github.com/yukiotakakura/laravel-fargate-infra2/pull/9/files

コメント

タイトルとURLをコピーしました