aws / chalice

Python Serverless Microframework for AWS
Apache License 2.0
10.59k stars 1.01k forks source link

Terraform: Better integration with non-chalice managed resources #1988

Open dhay opened 1 year ago

dhay commented 1 year ago

When using Terraform support, I'd like to see the ability to better integrate a chalice application with non-chalice resources. For example, if I create an SQS queue in Terraform, it would be nice to be able to define some variables in the chalice.tf.json file that could be referenced by, say, the environment variables passed to the Lambda function. Conversely, if I need to reference the ARN of a function from my non-chalice Terraform, I'd like to be able to augment the outputs with that information. (e.g. to integrate with Event Bridge, which isn't supported yet)

cobyforrester commented 1 year ago

I was able to find one way passing of resources, from terraform to chalice, with a clever hack I found somewhere on the internet.

The general idea is to have terraform generate the .chalice/config.json. So you would have a .chalice/base-config.json that terraform will use to generate a real .chalice/config.json.

.chalice/base-config.json

{
    "version": "2.0",
    "app_name": "french-vocab-api",
    "lambda_timeout": 300,
    "stages": {
      "dev": {
        "api_gateway_stage": "api",
        "manage_iam_role": true,
        "environment_variables": {
          "DB_USERNAME": "%s",
          "DB_PASSWORD": "%s",
          "DB_ENDPOINT": "%s"
        }
      }
    }
  }

main.tf

resource "local_file" "chalice_config" {
  # Output vars to chalice config
  filename = "${var.api_path}/.chalice/config.json"
  content  = "${format(file("${var.api_path}/.chalice/base-config.json"), var.db_username, var.db_password, aws_db_instance.endpoint)}"

  # Deploy via chalice
  provisioner "local-exec" {
    command     = "rm -fr .chalice/deployed && rm -fr .chalice/deployments && chalice deploy --profile $PROFILE"
    working_dir = "${path.module}/../api"
    environment = {
      AWS_DEFAULT_REGION    = "us-east-1"
    }
  }

  provisioner "local-exec" {
    when        = "destroy"
    command     = "chalice delete --profile $PROFILE"
    working_dir = "${path.module}/../api"

    environment = {
      AWS_DEFAULT_REGION    = "us-east-1"
    }
  }
}

Yes it is not perfect, but it has worked flawlessly for me so far, and allows me to pass terraform variables easily in. But if you do this, you need to have chalice cli on the shell you run terraform apply with, and you need to gitignore .chalice/config.json

Another possible solution is to use a secret manager, through aws or tooling like Doppler, and both your lambda function and terraform code I imagine could write and read from it.

An official solution would be great, though!

dhay commented 1 year ago

We’ve worked around the issue, for now by generating the chalice.tf.json file and the patching it with another Python script.