我如何告诉 Terraform 它应该根据输入变量部署一个完全独立的 API 网关?

How can I tell Terraform that it should deploy a completely separate API Gateway based on input variables?

我们在 vars 中有一个前缀,它基于名为 deployment_name_modifier 的输入。

  prefix    = (length(var.deployment_name_modifier) != 0) ? 
    "${var.environment}-${var.deployment_name_modifier}-${local.service_name}" :  
    "${var.environment}-${local.service_name}"

这是 API 网关设置(当然不是全部):

resource "aws_apigatewayv2_api" "ui_backend_gateway" {
  name          = "${local.prefix}-gateway"
  protocol_type = "HTTP"
  cors_configuration {
    allow_origins = var.environment == "prd" ? ["foo.bar.services"] : ["*"]
    allow_methods = ["POST", "OPTIONS", "HEAD"]
    allow_headers = [
      "Content-Type", "X-Amz-Date", "X-Amz-Security-Token",
      "Authorization", "X-Api-Key", "X-Requested-With", "Accept", "Access-Control-Allow-Methods",
      "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "referer", "origin",
      "access-control-request-method", "sec-*"
    ]
    max_age = 300
  }
}

我想要得到的是一个带有 Lambda 和 API 网关的功能分支,该分支连接到它自己的子域,而主分支位于一组单独的资源上。

问题是应用这个设置 deployment_name_modifier 的配置工作正常——直到我部署 master。当我使用 deployment_name_modifier 部署 master 时,Terraform 将功能分支中的子域应用到已经存在的 API 网关。我通过比较两个节目计划看到了这一点。这意味着主分支资源集的子域从 dev.foo.bar.servicesdev-1234.foo.bar.services。我真正需要的是:

dev.foo.bar.services -> API A -> Lambda A 

dev-1234.foo.bar.services -> API B -> Lambda B

其中A是master分支,B是feature分支(1234是票号,是分支名称的一部分)。更改 aws_apigatewayv2_api 阶段的名称显然是不够的。

如何让 Terraform 相信我真的想要两个完全独立的 API 基于输入变量的网关?

如果我需要在这里添加一些东西(也许是子域配置?)请在评论中告诉我。

地形 1.1.3

我通常会通过引入工作区兄弟来实现状态文件和计划文件的分离!如果您的 terraform 文件共享不同环境的状态,您的脚本将破坏以前的 api 网关和 lambda 函数!这是我的 PLAN 自动化脚本的示例:

#!/bin/bash
# Script will stop if any error is thrown
set -e

ENV_NAME="demo" # Could be changed to prod
WORKSPACE_NAME="upload-apis-${ENV_NAME}"
PLAN_FILE="./.plans/${ENV_NAME}_tf_plan"
PLAN_DIR="./.plans"

#source $ENV_FILE;

if test -d "$PLAN_DIR"; then
  echo "Plan directory already exists"
else
  echo "Creating plan directory"
  mkdir ./.plans
fi

# Initialize without remote state to execute validation
terraform init -backend=false

# Script will stop if any validation issue is found
terraform validate

# Initialize terraform with remote state after validation
terraform init

# Beautify code format of TF files
terraform fmt .

WS_COUNT=$(terraform workspace list | grep "$WORKSPACE_NAME" | wc -l)

# Create workspace if not exists
if [[ $WS_COUNT == 0 ]]; then
  terraform workspace new "$WORKSPACE_NAME"
fi

terraform workspace select "$WORKSPACE_NAME"

terraform plan -out="${PLAN_FILE}" -var-file="./envs/${ENV_NAME}.tfvars"

echo "Plan file is saved into ${ENV_NAME}_${PLAN_FILE}"

和我的 apply 脚本

#!/bin/bash
ENV_NAME="demo" # Could be changed to prod
WORKSPACE_NAME="upload-apis-${ENV_NAME}"
PLAN_FILE="./.plans/${ENV_NAME}_tf_plan"

terraform workspace select "$WORKSPACE_NAME"

terraform apply "${PLAN_FILE}"

如果您想 re-use 您的代码库,一种方法是通过 TF 的 workspaces:

A common use for multiple workspaces is to create a parallel, distinct copy of a set of infrastructure in order to test a set of changes before modifying the main production infrastructure.