使用Terraform极速部署Next.js网站到S3

「AWS?好像很难懂……」

「试过用AWS,但按钮太多,搞不清楚……」

「Terraform?没听说过……」

其实,直到最近我也是这样想的。但即使是我,也能使用Terraform构建网站。在本文中,我将分享如何使用AWS和Terraform将Next.js网站部署到S3的过程!

用到的工具

  • Terraform
  • Node.js
  • AWS CLI

创建并构建Next.js项目

首先,创建要部署的项目。

$ npx create-next-app@latest
Need to install the following packages:
create-next-app@14.2.4
Ok to proceed? (y) y

✔ What is your project named? … frontend
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
Creating a new Next.js app in /app/frontend.

next.config.js 修改为以下内容:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: "export",
  trailingSlash: true,
};

export default nextConfig;

package.json 中的 scripts 修改为以下内容:

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "export": "next export"
  }
}

执行以下命令来构建项目并创建 out 文件夹:

npm run build

接下来将生成的 out 文件夹通过 Terraform 上传到 S3。

使用 Terraform 配置 AWS 资源

provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_s3_bucket" "web_hosting_bucket" {
  bucket = "test-deployed-by-terraform"

  force_destroy = true
}

resource "aws_s3_bucket_public_access_block" "web_hosting_bucket_public_access_block" {
  bucket = aws_s3_bucket.web_hosting_bucket.id

  block_public_acls       = false
  block_public_policy     = false
  ignore_public_acls      = false
  restrict_public_buckets = false
}

resource "aws_s3_bucket_policy" "bucket_policy" {
  bucket = aws_s3_bucket.web_hosting_bucket.id
  policy = data.aws_iam_policy_document.policy_document.json
  depends_on = [
    aws_s3_bucket_public_access_block.web_hosting_bucket_public_access_block, # パブリックアクセスブロックの設定を待たないとエラーが発生する
  ]
}

data "aws_iam_policy_document" "policy_document" {
  statement {
    sid    = "Statement1"
    effect = "Allow"
    principals {
      type        = "*"
      identifiers = ["*"]
    }
    actions = [
      "s3:GetObject"
    ]
    resources = [
      "${aws_s3_bucket.web_hosting_bucket.arn}/*"
    ]
  }
}

resource "aws_s3_bucket_website_configuration" "web_hosting_bucket_config" {
  bucket = aws_s3_bucket.web_hosting_bucket.id

  index_document {
    suffix = "index.html"
  }

  error_document {
    key = "error.html"
  }
}

module "template_files" {
  source   = "hashicorp/dir/template"
  base_dir = "../frontend/out" # Build文件夹
}

resource "aws_s3_object" "bucket_object" {
  for_each     = module.template_files.files
  bucket       = aws_s3_bucket.web_hosting_bucket.id
  key          = each.key
  source       = each.value.source_path
  content_type = each.value.content_type
  etag         = filemd5(each.value.source_path)
}

解説

● 设置AWS提供者,指定东京区域(ap-northeast-1)
● 创建S3存储桶
  ● 存储桶名称:"test-deployed-by-terraform"
  ● 设置 `force_destroy: true`,即使有内容也可以删除
● 允许存储桶的所有公共访问设置
● 配置存储桶策略
  ● 赋予所有用户 `GetObject` 权限
● 将存储桶配置为网站托管
  ● 索引文档:`index.html`
  ● 错误文档:`error.html`
● 使用模板文件模块读取本地文件
● 创建S3对象资源
  ● 将模板文件模块读取的文件上传到S3
  ● 设置内容类型和ETAG(用于检测上传文件的更改)

Terraform执行

terraform init   # 初期化
terraform plan   # 確認PLAN
terraform apply -auto-approve # release

确认部署内容

AWS 控制台→S3 详细信息页面→属性→静态网站托管的存储桶网站端点,访问该端点后,您应该会看到以下画面。 至此,部署完成。

写在最后

感觉如何?就我个人而言,我发现使用Terraform以代码的形式管理和执行基础设施,比手动操作AWS控制台界面要简单得多。这样一来,使用AWS的门槛也降低了。(毕竟,AWS的控制台界面功能太多,很难找到需要操作的地方……)

  • 15
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值