Terraform 基础设施
Terraform 是一个开源的基础设施即代码软件工具,使您能够安全且可预测地创建、更改和改进基础设施。
Terraform 基础设施生成器创建一个 Terraform 基础设施项目。生成的应用程序通过 Checkov 安全检查包含安全最佳实践。
生成 Terraform 项目
Section titled “生成 Terraform 项目”您可以通过两种方式生成新的 Terraform 项目:
运行此生成器@aws/nx-plugin:terraform#project
pnpm nx g @aws/nx-plugin:terraform#project yarn nx g @aws/nx-plugin:terraform#project npx nx g @aws/nx-plugin:terraform#project bunx nx g @aws/nx-plugin:terraform#project- 安装 Nx Console VSCode Plugin 如果您尚未安装
- 在VSCode中打开Nx控制台
- 点击
Generate (UI)在"Common Nx Commands"部分 - 搜索
@aws/nx-plugin - terraform#project - 填写必需参数
- 点击
Generate
构建你的命令5
必需
name必需string项目的名称。
typeenum默认值:application项目类型,是 terraform 库(可重用模块)还是应用(可部署)。
applicationlibrarydirectorystring默认值:packages新项目的目录。
subDirectorystring项目所在的子目录。默认为项目名称。
preferInstallDependenciesboolean默认值:true是否在生成器运行后优先安装依赖项。设置为 false 可在批量运行多个生成器时延迟安装(如果后续生成器需要计算 Nx 项目图,仍会运行安装);在最后统一安装一次。
生成器根据项目类型创建不同的文件结构:
应用程序类型
Section titled “应用程序类型”对于应用程序项目(--type=application),生成器创建一个完整的 Terraform 应用程序,具有远程状态管理:
文件夹src
- main.tf 主 Terraform 配置文件
- providers.tf 带有 S3 后端的提供程序配置
- variables.tf 输入变量定义
- outputs.tf 输出值定义
文件夹env 特定环境的变量文件
- dev.tfvars 开发环境变量
文件夹bootstrap 远程状态的引导配置
- main.tf 用于状态存储的 S3 存储桶和策略
- providers.tf AWS 提供程序配置
- variables.tf 引导变量定义
文件夹scripts 由 nx
bootstrap、bootstrap-destroy和init目标运行的 Node 辅助程序- aws-config.ts 通过 AWS SDK 凭证链解析账户 + 区域
- bootstrap.ts 拉取/推送引导 tfstate 并运行
terraform apply - bootstrap-destroy.ts 清空状态存储桶并运行
terraform destroy - init.ts 使用 S3 后端配置运行
terraform init - env.ts 将
terraform init指向共享提供程序缓存
- checkov.yml Checkov 配置,包括要跳过的检查
- project.json 项目配置和构建目标
对于库项目(--type=library),生成器为可重用的 Terraform 模块创建一个更简单的结构:
文件夹src
- main.tf 主 Terraform 模块文件
- checkov.yml Checkov 配置,包括要跳过的检查
- project.json 项目配置和构建目标
实现您的 Terraform 基础设施
Section titled “实现您的 Terraform 基础设施”您可以在 src/main.tf 中开始编写您的 Terraform 基础设施,例如:
locals { account_id = data.aws_caller_identity.current.account_id aws_region = data.aws_region.current.id}
resource "null_resource" "print_info" { # triggers = { # always_run = timestamp() # }
provisioner "local-exec" { command = "echo 'AWS Region: ${local.aws_region}, AWS Account: ${local.account_id}, Environment: ${var.environment}'" }}
# Declare your infrastructure hereresource "aws_s3_bucket" "my_bucket" { bucket = "my-unique-bucket-name"}请注意,上面的 S3 存储桶将无法通过 Checkov 安全扫描,该扫描会检查存储桶是否启用了适当的安全设置。
如果您想从单独的项目(库)执行模块,可以按如下方式操作:
module "lib_module" { source = "../../path/to/my-lib/src"}这将自动更新 Nx 图,在您的使用应用程序和您的库之间添加依赖关系。
在 src/env/*.tfvars 文件中配置特定环境的变量。
要添加新环境,请创建一个新的 src/env/<environment>.tfvars 文件,其中包含特定环境的变量,并在 project.json 中为新环境配置添加 apply, destroy, init, plan 的新条目。例如,假设我们想添加一个 prod 环境:
# Production environment variablesenvironment = "prod"aws_region = "us-west-2"{ "targets": { "apply": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "command": "terraform apply ../../../dist/packages/infra/terraform/dev.tfplan" }, "prod": { "command": "terraform apply ../../../dist/packages/infra/terraform/prod.tfplan" } }, "options": { "forwardAllArgs": true, "cwd": "{projectRoot}/src" }, "dependsOn": ["plan"] }, "destroy": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "command": "terraform destroy -var-file=env/dev.tfvars" }, "prod": { "command": "terraform destroy -var-file=env/prod.tfvars" } }, "options": { "forwardAllArgs": true, "cwd":"{projectRoot}/src" }, "dependsOn": ["init"] }, "init": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "env": { "TF_ENV": "dev" } }, "prod": { "env": { "TF_ENV": "prod" } } }, "options": { "forwardAllArgs": true, "commands": ["tsx {projectRoot}/scripts/init.ts {projectRoot}"], "cwd": "{workspaceRoot}" } }, "plan": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "command": "terraform plan -var-file=env/dev.tfvars -out=../../../dist/packages/infra/terraform/dev.tfplan" }, "prod": { "command": "terraform plan -var-file=env/prod.tfvars -out=../../../dist/packages/infra/terraform/prod.tfplan" } }, "options": { "forwardAllArgs": true, "cwd": "{projectRoot}/src" }, "dependsOn": ["init"] } }}远程状态引导(仅限应用程序项目)
Section titled “远程状态引导(仅限应用程序项目)”在部署基础设施之前,您需要引导远程状态后端。这将创建一个 S3 存储桶来存储您的 Terraform 状态文件:
pnpm nx bootstrap tf-infrayarn nx bootstrap tf-infranpx nx bootstrap tf-infrabunx nx bootstrap tf-infra可用目标取决于您的项目类型:
通用目标(应用程序和库)
Section titled “通用目标(应用程序和库)”验证您的基础设施
Section titled “验证您的基础设施”您可以使用 validate 目标验证您的 Terraform 配置:
pnpm nx validate tf-infrayarn nx validate tf-infranpx nx validate tf-infrabunx nx validate tf-infraLinting
Section titled “Linting”Terraform 项目使用 terraform fmt 来检查格式。
运行 Linter
Section titled “运行 Linter”要调用 linter 检查您的项目,您可以运行 lint 目标。
pnpm nx lint tf-infrayarn nx lint tf-infranpx nx lint tf-infrabunx nx lint tf-infra修复 Lint 问题
Section titled “修复 Lint 问题”大多数 linting 或格式化问题可以通过使用 --configuration=fix 参数运行来自动修复。
pnpm nx lint tf-infra --configuration=fixyarn nx lint tf-infra --configuration=fixnpx nx lint tf-infra --configuration=fixbunx nx lint tf-infra --configuration=fix同样,如果您想修复工作区中所有包的所有 lint 问题,可以运行:
pnpm nx run-many --target lint --all --configuration=fixyarn nx run-many --target lint --all --configuration=fixnpx nx run-many --target lint --all --configuration=fixbunx nx run-many --target lint --all --configuration=fix跳过 Lint 问题
Section titled “跳过 Lint 问题”为了避免在开发过程中 linting 问题拖慢您的速度(特别是如果您的项目中有无法自动修复的问题),您可以使用 skip-lint 配置运行构建:
pnpm nx run-many --target build --configuration=skip-lintyarn nx run-many --target build --configuration=skip-lintnpx nx run-many --target build --configuration=skip-lintbunx nx run-many --target build --configuration=skip-lint这会在构建期间完全跳过格式检查。
使用 Checkov 通过 checkov 目标对您的基础设施运行安全检查:
pnpm nx checkov tf-infrayarn nx checkov tf-infranpx nx checkov tf-infrabunx nx checkov tf-infra您将在根 dist 文件夹下的 dist/packages/<my-terraform-project>/checkov 中找到您的安全测试结果。
Checkov 作为 build 的一部分运行。
检查在项目的 checkov.yml 中配置。将检查 ID 添加到 skip-check 以在整个项目中抑制它:
skip-check: - CKV_AWS_115 # Concurrent execution limit - CKV_AWS_116 # Dead Letter Queue要仅对单个资源抑制检查,请在资源块内添加 #checkov:skip=<id>:<reason> 注释:
resource "aws_s3_bucket" "example" { #checkov:skip=CKV_AWS_18:Access logging not required for this bucket bucket = "example"}运行 Terraform 测试
Section titled “运行 Terraform 测试”test 目标在项目中的任何 .tftest.hcl 文件上运行 Terraform 的原生测试框架:
pnpm nx test tf-infrayarn nx test tf-infranpx nx test tf-infrabunx nx test tf-infra没有测试文件的项目是无操作成功,因此您可以在需要时添加测试。build 运行此目标,因此您的测试作为正常构建的一部分运行。
每个 run 块评估您的配置。使用 command = plan 检查 Terraform _将会_执行的操作(这会展开整个模块图,因此它可以捕获 validate 无法捕获的计划时错误),或使用 command = apply 创建真实资源并断言其输出。声明 mock_provider 意味着不会进行 API 调用,也不需要 AWS 凭证,这使得 plan 测试快速且可以安全地在 CI 中运行:
mock_provider "aws" { mock_data "aws_caller_identity" { defaults = { account_id = "123456789012" } } mock_data "aws_region" { defaults = { region = "us-east-1" } }}
variables { aws_region = "us-east-1" environment = "dev"}
run "plan_is_valid" { command = plan
assert { condition = data.aws_caller_identity.current.account_id == "123456789012" error_message = "Unexpected account id" }}在 variables 块中设置配置所需的每个变量,否则运行将失败并显示”has a required variable … with no set value”。
每个运行 terraform init 的目标都在工作区根目录的 .terraform/plugin-cache 下重用提供程序缓存,因此提供程序只下载一次而不是每次运行时都下载。每个项目在那里都有自己的目录:两个 terraform init 运行同时填充一个缓存时,每个都可能为同一个提供程序计算不同的哈希值,然后 terraform 会根据您的 .terraform.lock.hcl 拒绝它。有关更多信息,请参阅 Terraform 文档。
在您的环境中设置 TF_PLUGIN_CACHE_DIR 以将提供的 init 脚本指向您自己管理的缓存——例如在工作区之间共享的卷。请注意,test 目标从 project.json 读取其路径,因此也要在那里更改它。
仅限应用程序的目标
Section titled “仅限应用程序的目标”以下目标仅适用于应用程序类型项目:
规划您的基础设施
Section titled “规划您的基础设施”在应用更改之前,您可以通过运行 plan 目标来查看 Terraform 将执行的操作:
pnpm nx plan tf-infrayarn nx plan tf-infranpx nx plan tf-infrabunx nx plan tf-infra这将在 dist/packages/<my-terraform-project>/terraform/dev.tfplan 中创建一个计划文件。
plan 依赖于 assemble,因此它会生成您的模块引用的工件,例如 Lambda 包和生成的操作元数据,而不运行 lint、test 和 type-check 门控。
初始化 Terraform
Section titled “初始化 Terraform”使用 init 目标初始化您的 Terraform 工作目录:
pnpm nx run tf-infra:inityarn nx run tf-infra:initnpx nx run tf-infra:initbunx nx run tf-infra:init部署到 AWS
Section titled “部署到 AWS”规划后,您可以使用 apply 目标将基础设施部署到 AWS:
pnpm nx apply tf-infrayarn nx apply tf-infranpx nx apply tf-infrabunx nx apply tf-infra从您的 Terraform 配置中检索输出值:
pnpm nx output tf-infrayarn nx output tf-infranpx nx output tf-infrabunx nx output tf-infra销毁基础设施
Section titled “销毁基础设施”当您需要拆除基础设施时,使用 destroy 目标:
pnpm nx destroy tf-infrayarn nx destroy tf-infranpx nx destroy tf-infrabunx nx destroy tf-infra销毁引导资源
Section titled “销毁引导资源”要清理引导资源(用于状态存储的 S3 存储桶):
pnpm nx bootstrap-destroy tf-infrayarn nx bootstrap-destroy tf-infranpx nx bootstrap-destroy tf-infrabunx nx bootstrap-destroy tf-infra这会在销毁状态存储桶之前清空它,并从 AWS SDK 凭证链解析区域,因此它可以在 CI 中无人值守运行。
有关 Terraform 的更多信息,请参阅 Terraform 文档和 AWS 提供程序文档。