【问题标题】:How can I tell Terraform that it should deploy a completely separate API Gateway based on input variables?我如何告诉 Terraform 它应该基于输入变量部署一个完全独立的 API 网关?
【发布时间】:2022-01-22 10:29:28
【问题描述】:

我们在 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.services 变为dev-1234.foo.bar.services。我真正需要的是:

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

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

其中 A 是主分支,B 是功能分支(1234 是票号,它是分支名称的一部分)。更改aws_apigatewayv2_api 舞台的名称显然是不够的。

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

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

地形 1.1.3

【问题讨论】:

  • 进展如何?仍然不清楚为什么你不能这样做?
  • @Marcin “问题是使用部署名称修改器集应用此配置工作正常 - 直到我部署主服务器。当我使用部署名称修改器空部署主服务器时,Terraform 正在将子域从功能分支应用到 API已经存在的网关”

标签: amazon-web-services aws-lambda terraform aws-api-gateway


【解决方案1】:

如果您想重用您的代码库,一种方法是通过 TF 的workspaces

多个工作区的常见用途是创建一组基础架构的并行不同副本,以便在修改主要生产基础架构之前测试一组更改。

【讨论】:

    【解决方案2】:

    我通常会通过引入工作区来实现状态和计划文件的分离兄弟!如果您的 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}"
    

    【讨论】:

    • 好的,这很有帮助。一个问题:为什么在部署过程中格式化 TF 文件?我们在预提交脚本中有它。
    • 我也想知道你为什么把这两个进程放在两个文件中——更好的失败?我注意到第二个没有 set -e ...
    • @jcollum,因为这是 TF 中检查我们模板的计划更新路线的最佳实践!它可以防止大多数灾难:D 当 TF 计划中的一切都很好时,我们会应用更改
    • 啊,我们作为 CICD 的一部分执行此操作,因此实际上没有检查点。这就是为什么我们要首先部署到功能分支基础设施。
    猜你喜欢
    • 1970-01-01
    • 2019-05-31
    • 2021-09-12
    • 2023-03-27
    • 2020-01-14
    • 2017-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多