Using lifecycle_scope with vTGW/TGW peering in VMware Cloud on AWS
Terraform example: demonstrates using the lifecycle_scope option in aws_lambda_invocation for vTGW/TGW peering
Situation
My team runs a customer-facing Immersion Day, which is a hands-on event allowing customers to work in a live VMware Cloud on AWS SDDC, as well as work with native AWS services in a live AWS account. The VMC on AWS side of the lab contains 2 SDDCs connected via a VMware Transit Gateway (vTGW). The AWS native side of the lab contains student VPCs peered to a native Transit Gateway. The vTGW and native TGW are peered for seamless communication. The lab environment is provisioned with a combination of Terraform and Cloud Formation.
Task
My team has been using a Python script to create and destroy the vTGW-TGW peering connection. While this was OK, I wanted to bake the process into our Terraform code and eliminate the extra Python step.
Actions
I knew that I wanted my Terraform code to create and invoke a Lambda function that would perform the peering. I had not used Terraform with Lambda before, so I started searching the documentation. I found a way to create a Lambda function, and a way to invoke a Lambda function.
In the aws_lambda_invocation documentation, I found an option called lifecycle_scope
. By default, a Lambda is only invoked on create or replacement. But the instruction lifecycle_scope = "CRUD"
will cause the Lambda to be invoked on all lifecycle events. This new feature, published in May 2023, gave me exactly what I wanted: my function can now create the vTGW-TGW peering when we run terraform apply
, and destroy the peering when we run terraform destroy
Listed below is how I defined the Lambda function and invocation in Terraform. You can see the Lambda input variables that I need to pass in order to make the VMC on AWS API call to initiate a vTGW-TGW peering. One item to highlight that really tripped me up is the line:
function_name = aws_lambda_function.vtgw_tgw_peering_lambda.function_name
.function_name
is an actual property, not a placeholder in the documentation. I was reading the documentation thinking that .function_name
was a placeholder and could not get it to work. I was trying to use:
# This is invalid aws_lambda_function.vtgw_tgw_peering_lambda.vtgw_tgw_lambda
This does not work because you need to use an actual property name: .function_name
.
resource "aws_lambda_function" "vtgw_tgw_peering_lambda" { filename = "lambda/vtgw_tgw_lambda_payload.zip" function_name = "vtgw_tgw_lambda" role = aws_iam_role.iam_role_for_lambda.arn handler = "index.lambda_handler" runtime = "python3.11" timeout = 600 memory_size = 512 layers = [aws_lambda_layer_version.lambda_layer.arn] } resource aws_lambda_invocation "vtgw_lambda" { function_name = aws_lambda_function.vtgw_tgw_peering_lambda.function_name input = jsonencode( { "vmc_refresh_token" = var.vmc_refresh_token, "vmc_org_id" = data.terraform_remote_state.phase1.outputs.vmc_org_id, "sddc_a_region" = data.terraform_remote_state.phase1.outputs.sddc_a_region, "sddc_a_id" = data.terraform_remote_state.phase1.outputs.sddc_a_id, "sddc_group_id" = data.terraform_remote_state.phase1.outputs.sddc_group_id, "aws_account_number" = data.terraform_remote_state.phase1.outputs.aws_account_number } ) lifecycle_scope = "CRUD" }
When you set lifecycle_scope="CRUD"
, Terraform injects a key named tf
with a subkey named action
to let you know which phase Terraform was in when invoking the Lambda.
This is a snippet of my Lambda handler showing how I read the action key and branched my code based on create/delete.
def lambda_handler(event, context): vmc_refresh_token = event['vmc_refresh_token'] vmc_org_id = event['vmc_org_id'] sddc_a_id = event['sddc_a_id'] sddc_a_region = event['sddc_a_region'] sddc_group_id = event['sddc_group_id'] aws_account_number = event['aws_account_number'] tf_action = event['tf']['action'] print(f"tf_action = {tf_action}") match tf_action: case "create": print("Peering vTGW with TGW...") case "delete": print("Deleting vTGW/TGW peering...")
Result
The new lifecycle_scope option lets me ensure that my Lambda can clean up after itself when a destroy operation is executed, and removes the need for a manual Python task every time my team provisions and destroys an Immersion Day.
相關內容
- 已提問 6 個月前lg...
- 已提問 8 個月前lg...
- AWS 官方已更新 2 年前
- AWS 官方已更新 3 年前
- AWS 官方已更新 1 年前
- AWS 官方已更新 2 年前