👽

TerraformでAmplifyを構築し、爆速でデプロイする

に公開

はじめに

今回は、Terraformを使って AWS Amplifyを構築し、React アプリケーション(今回はTypeScriptとViteで構築した、アスキーアートを表示するシンプルなアプリです)を自動でデプロイする方法について解説していこうと思います。

Amplifyとは

AWS Amplify は、モバイルおよびフロントエンドの Web アプリケーションを迅速に開発、デプロイ、ホスティングするためのフルスタックなプラットフォームです。
バックエンドの認証、データベース、API などの機能から、フロントエンドのホスティング(静的 Web サイトの公開)まで、アプリケーション開発に必要な幅広いサービスを提供しています。

構成イメージ


Terraform を用いて Amplifyアプリケーションをプロビジョニングし、GitHub リポジトリと連携させます。
AmplifyがGitHubリポジトリにアクセスし、コードを取得するために、GitHub PAT(Personal Access Token)を使用して認証を行います。
また、今回はReact bitsというライブラリを用いてAsciiTextを作成し、Amplifyにデプロイしていこうと思います。
(React bitsの導入手順は本記事の範囲外のため割愛します)

実際に使用したコードや構成ファイルは以下の GitHub リポジトリで公開しています。
https://github.com/anton-fuji/terraform_amplify

ファイル構成

以下のファイルを用意してください。

├── app/                  # デプロイするアプリケーション用のディレクトリ
│   
└── infra/                
    ├── main.tf           # プロバイダの定義とTerraformバージョン
    ├── amplify.tf        # AWS Amplifyのリソース定義
    ├── variables.tf      # 変数定義
    ├── outputs.tf        # デプロイ後の出力
    └── terraform.tfvars  # githubのURL・PAT

main.tf

main.tfでは、プロバイダのバージョン要件を定義していきます。

provider "aws" {
  region = var.aws_region
}

terraform {
  required_version = ">= 1.0.0"
  required_providers {
    aws = {
        source = "hashicorp/aws"
        version = "~> 5.0"
    }
  }
}
  • required_version
    • Terraformを構成するために必要なTerraform CLIのバージョンを指定します
  • required_providers
    • 使用するプロバイダ(ここではAWS)とそのソース・バージョンを定義していきます

amplify.tf

amplify.tf では、AWS Amplifyのアプリケーションとデプロイするブランチを定義するファイルです。

# Amplifyのリソース
resource "aws_amplify_app" "my_ascii_react" {
  name       = var.amplify_app_name
  repository = var.github_repository_url
  oauth_token = var.github_oauth_token
  platform = "WEB"
  

  # Amplifyがアプリケーションをビルドするための設定(build_spec)
  build_spec = <<-EOT
    version: 1
    frontend:
      phases:
        preBuild:
          commands:
            - cd app 
            - npm ci
        build:
          commands:
            - npm run build
      artifacts:
        baseDirectory: app/dist
        files:
          - '**/*'
      cache:
        paths:
          - app/node_modules/**/*
  EOT
}   

# デプロイするブランチの定義
resource "aws_amplify_branch" "main_branch_deployment" {
    app_id = aws_amplify_app.my_ascii_react.id
    branch_name = var.amplify_branch_name
    stage = "PRODUCTION"
}

3つのセクションに分けて順に解説していきます。

Amplifyリソースの基本設定

resource "aws_amplify_app" "my_ascii_react" {
  name       = var.amplify_app_name
  repository = var.github_repository_url
  oauth_token = var.github_oauth_token
  platform = "WEB"
 # ... (build_specは次のセクションで解説)
}
  • resource "aws_amplify_app" "my_ascii_react"
    • Amplifyのアプリケーションリソースを定義
    • my_ascii_reactはterraform内で、このリソースを識別するための名
  • name = var.amplify_app_name
    • Amplify コンソールに表示されるアプリケーション名
    • variables.tf で定義した変数を使用
  • repository = var.github_repository_url
    • アプリケーションのソースコードが格納されているGitHubリポジトリのURLを指定
  • oauth_token = var.github_oauth_token
    • Amplify がGitHubリポジトリにアクセスするための認証トークン(GitHub PAT
  • platform = "WEB"
    • アプリケーションの種類がWebアプリケーションであることを示します

build_specについて

続いて、Amplify がアプリケーションをビルドするための詳細な手順をbuild_spec で定義します。
これはYAML形式で記述されます。
以下は、私のディレクトリ構成に合わせて作成した build_specです。

  build_spec = <<-EOT
    version: 1
    frontend:
      phases:
        preBuild:
          commands:
            - cd app 
            - npm ci
        build:
          commands:
            - npm run build
      artifacts:
        baseDirectory: app/dist
        files:
          - '**/*'
      cache:
        paths:
          - app/node_modules/**/*
  EOT
  • version
    • build_specのスキーマバージョン
  • phases
    • ビルドの各段階(preBuild, build)で実行するコマンドを定義
  • artifacts
    • ビルド後にAmplifyがホスティングする成果物の場所を指定
    • 今回はapp/dist直下にビルド後のファイルが生成されるので、そこを指定
    • files*を指定しておけば全てのファイルとサブディレクトリをデプロイ対象にできる
  • cache
    • ビルドキャッシュの設定
    • app/node_modules/**/*はnode_modules ディレクトリをキャッシュすることで、次回のビルド時間を短縮できます

デプロイブランチの定義

最後に、どのブランチをAmplifyにデプロイするか、そのステージ設定を定義します。

resource "aws_amplify_branch" "main_branch_deployment" {
    app_id = aws_amplify_app.my_ascii_react.id
    branch_name = var.amplify_branch_name
    stage = "PRODUCTION"
}
  • app_id = aws_amplify_app.my_ascii_react.id
    • ブランチが紐付くAmplifyのIDを指定
    • ここでは、同じファイル内で定義したaws_amplify_app.my_ascii_react リソースの idを参照しています
    • これにより、Terraformがリソース間の依存関係を自動的に解決します

outputs.tf

Terraformの実行完了後に、デプロイされたAmplifyアプリケーションのURLやIDをターミナルで確認できるように出力します。

output "amplify_app_url" {
  description = "The default URL of the deployed Amplify application."
  value       = aws_amplify_app.my_ascii_react.default_domain
}

output "amplify_app_id" {
  description = "The ID of the Amplify App."
  value       = aws_amplify_app.my_ascii_react.id
}

variables.tf

# リージョンの定義
variable "aws_region" {
  description = "To deploy resources."
  type        = string
  default     = "ap-northeast-1"
}

# Amplifyアプリケーションの名前
variable "amplify_app_name" {
  description = "The name of the Amplify App."
  type        = string
  default     = "my-ascii-react-app"
}

# GitHubリポジトリのURL
variable "github_repository_url" {
  description = "The URL of the GitHub repository containing the React app."
  type        = string
  default = "<ここにデプロイしたいGitHubリポジトリのURL>"
}

# GitHub OAuth Token
variable "github_oauth_token" {
  description = "GitHub OAuth Token with 'repo' scope for Amplify to access the repository."
  type        = string
  sensitive   = true 
}

variable "amplify_branch_name" {
  description = "The branch name to deploy in Amplify."
  type        = string
  default     = "main"
}

github_oauth_tokensensitive をtrueにすると、Terraform の出力ログに値が表示されなくなり、外部に漏洩するリスクを低減できます。

terraform.tfvarsの設定

Terraformの変数の値は、terraform.tfvarsに記述することで渡すことができます。
GitHub PATなどのシークレットや、プロジェクト固有の環境変数をここで記述すると良いでしょう。terraform.tfvars に以下の内容を加えてください。

github_oauth_token= "<GitHub PATの入力>"
github_repository_url = "<Repo URL>"

GitHub PATの取得手順は、GitHubで個人アクセストークンを発行する方法に具体的な手順が載っています。
スコープには、repoadmin:repo_hookにチェックを入れてPATを取得してください。

デプロイしていきましょう!

以下の手順で作業を進めてください。

# infraディレクトリへ移動
cd infra

terraform init

terraform apply --auto-approve

Terraform の実行が完了すると、以下のようなログが出力され、Amplify リソースの作成が完了したことを示します。

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

コンソールに移動

AWSマネジメントコンソールでAmplifyへ移動して、my_ascii_react_appがあることを確認。

あとは「ジョブを実行」をするだけで、デプロイが完了します。

デプロイが完了したら、URLにアクセスし正常に「やっほ〜!」が表示されていればOKです!


やっほ〜!

まとめ

Amplify、超便利 👍

参考

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/amplify_app

Discussion