Home > Enterprise >  How can I tell Terraform that it should deploy a completely separate API Gateway based on input vari
How can I tell Terraform that it should deploy a completely separate API Gateway based on input vari

Time:01-22

We have a prefix in vars that is based on an input called deployment_name_modifier.

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

This is the API Gateway setup (not all of it of course):

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
  }
}

What I'm trying to get to is a feature branch with a Lambda and API Gateway that is wired to a subdomain of its own while the master branch is on a separate set of resources.

The problem is that applying this configuration with deployment_name_modifier set is working fine -- until I deploy master. When I deploy master with deployment_name_modifier empty Terraform is applying the subdomain from the feature branch to the API Gateway that is already in place. I have seen this by diffing the two show plans. Meaning that the subdomain for the master branch set of resources goes from dev.foo.bar.services to dev-1234.foo.bar.services. What I actually need is:

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

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

Where A is the master branch and B is the feature branch (1234 is a ticket number, which is part of the branch name). Changing the name of the aws_apigatewayv2_api stage is apparently not enough.

How can I convince Terraform that I really actually want two completely separate API Gateways based on input variables?

If I need to add something here (maybe the subdomain config?) please let me know in a comment.

Terraform 1.1.3

CodePudding user response:

I would usually implement a separation of state and plan files by introducing workspace bro! If your terraform files share state for different environments, your script will destroy the previous api gateway and lambda function! Here is a sample of my PLAN automation script:

#!/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}"

and my apply script

#!/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}"

CodePudding user response:

If you want to re-use your codebase, one way to do this is through TF's 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.

  •  Tags:  
  • Related