Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AWS Synthetics Canary Missing support for Environment Variables #17948

Closed
dj-maisy opened this issue Mar 5, 2021 · 13 comments · Fixed by #23574
Closed

AWS Synthetics Canary Missing support for Environment Variables #17948

dj-maisy opened this issue Mar 5, 2021 · 13 comments · Fixed by #23574
Labels
enhancement Requests to existing resources that expand the functionality or scope. service/synthetics Issues and PRs that pertain to the synthetics service. upstream Addresses functionality related to the cloud provider.
Milestone

Comments

@dj-maisy
Copy link

dj-maisy commented Mar 5, 2021

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Description

At present, it would appear the AWS Provider does not yet support the ability to set environment variables for aws_synthetics_canary resources. As they share some similarities, I was expecting canary resources to support environment variables in a much similar fashion to Lambda Functions.

It would appear that in the original PR to add canary support, there was a attempt to bring in support for environment variables which was subsequently reverted, presumably due to some kind of bug or limitation somewhere. If this was indeed the case, then it would be nice to have this feature included again whenever possible.

New or Affected Resource(s)

  • aws_synthetics_canary

Potential Terraform Configuration

resource "aws_synthetics_canary" "some_canary_test" {
  name                 = "some_canary_test"
  artifact_s3_location = aws_s3_bucket.some_canary_test_bucket.id
  execution_role_arn   = aws_iam_role.some_canary_test_role.arn
  handler              = "test.handler"

  zip_file             = "placeholder_smoke_test.zip"

  runtime_version      = "syn-nodejs-puppeteer-3.1"

  schedule {
    expression = "rate(60 minute)"
  }

  tags = {
    blueprint = "canaryRecorder"
  }

  # This is currently not supported.
  environment {
    variables = {
      API_TOKEN = "some_token_here"
    }
  }
}

References

@dj-maisy dj-maisy added the enhancement Requests to existing resources that expand the functionality or scope. label Mar 5, 2021
@ghost ghost added the service/synthetics Issues and PRs that pertain to the synthetics service. label Mar 5, 2021
@ewbankkit
Copy link
Contributor

Synthetics Canary environment variable support was made available in AWS SDK v1.35.29 but has not yet been implemented in the aws_synthetics_canary resource.

@omkarjoshi
Copy link

I am also looking for support to use ENV variables but its not currently not supported. I will raise a PR soon with relevant changes.

@brendan-sherrin
Copy link

brendan-sherrin commented Mar 15, 2021

Impact of this not being enabled:
Every time I update a aws_synthetics_canary resource it wipes the set environment variable with the url and I have to add it back.

I'm also looking to deploy canaries in bulk via for_each. This isue is blocking that since I can't assign url/strings to check with environmental variables and canaries don't allow feeding inputs with events like Lambda allows.

@duffers20
Copy link

We are also facing this issue. We wish to use a common script for running tests on all of our environments (e.g. dev/test/prod), but use an environment variable for the URL to access, and are unable to define this in our terraform scripts.

@shuheiktgw
Copy link
Collaborator

I looked into this issue and found CanaryRunConfigOutput does not have EnvironmentVariables attribute (CanaryRunConfigInput supports it). AWS does not seem to have other ways to retrieve the values hence I believe
Terraform AWS Provider cannot support it right now (aws-sdk-go v1.38.19)

@mbhatia53
Copy link

I am also looking for support to use ENV variables but its not currently not supported.

@ghost
Copy link

ghost commented Jun 8, 2021

My code is very similar and it fails with this error

ERROR: Canary error:
Error: Cannot find module '/opt/nodejs/node_modules/exports'Require stack:- /var/task/index.js- /var/runtime/UserFunction.js- /var/runtime/index.js

@davegallant
Copy link

davegallant commented Jun 30, 2021

I looked into this issue and found CanaryRunConfigOutput does not have EnvironmentVariables attribute (CanaryRunConfigInput supports it). AWS does not seem to have other ways to retrieve the values hence I believe
Terraform AWS Provider cannot support it right now (aws-sdk-go v1.38.19)

I neglected to read this comment and started to see if I could add this feature here, but then also discovered it is not possible to read the current environment variables from a canary, resulting in terraform plan always showing new variables being added.

I think this issue is not related to the aws-sdk-go, but the service's API itself.

I opened aws/aws-sdk-go#3982. Hopefully environment variables will be added in the future 😄 .

@dutchhaag
Copy link

I am also looking for support to use ENV variables but its not currently not supported.

@DrFaust92 DrFaust92 added the upstream Addresses functionality related to the cloud provider. label Jul 7, 2021
@BeejLuig
Copy link

BeejLuig commented Jul 26, 2021

I looked into this issue and found CanaryRunConfigOutput does not have EnvironmentVariables attribute (CanaryRunConfigInput supports it). AWS does not seem to have other ways to retrieve the values hence I believe
Terraform AWS Provider cannot support it right now (aws-sdk-go v1.38.19)

One way to grab the environment variables would be to grab the EngineArn from the GetCanary call, then pass that to the Lambda GetFunctionConfiguration call.

An example using the CLI and jq:

export ENGINE_ARN=$(aws synthetics get-canary --name=<canary_name> | jq '.Canary.EngineArn' | xargs)
aws lambda get-function-configuration --function-name=$ENGINE_ARN | jq '.Environment.Variables'             

Could this be a reasonable approach for the Terraform AWS provider? I'd love to see this feature in the Synthetics Canary resource too

@TonyLovesDevOps
Copy link
Contributor

TonyLovesDevOps commented Jan 27, 2022

Dear fellow nerds,

Given that the AWS API doesn't even support displaying the environment variables for a canary, it will probably take a long time to even be able to support this without a lot of hoop-jumping (e.g. querying the lambda API to get the current environment variables for the function the canary is tied to).

I put together the following code in my module to support setting environment variables at create time and whenever any of the run-config parameters change which are documented here.

A few caveats:

  • This code won't detect changes made to the environment variables outside of terraform
  • If any new run-config parameters are added, or if the aws update canary command spec changes in any way, this will break
  • The first execution of the canary will occur before the update-canary command runs, so the first run will happen without the environment variables
  • You must define values for all of the run-config parameters as omitting them will reset them to the defaults
  • This requires you to have the aws cli set up, configured to interact with the account in which terraform creates the canary, and you must have adequate permissions to update the canary

Without further ado, here's how I'm doing this:

locals {
  canary_name                   = "foo"
  canary_timeout_in_seconds     = 30
  canary_memory_limit_in_mb     = 960
  canary_active_tracing_enabled = false
  canary_environment_variables  = { FOO: "BAR" }
  set_canary_run_config_command = "aws synthetics update-canary --name ${local.canary_name} --run-config '${jsonencode({TimeoutInSeconds: local.canary_timeout_in_seconds, MemoryInMB: local.canary_memory_limit_in_mb, ActiveTracing: local.canary_active_tracing_enabled, EnvironmentVariables: local.canary_environment_variables })}'"
}

resource "aws_synthetics_canary" "healthchecks" {
  name                      = local.canary_name
  start_canary              = true
  s3_bucket                 = aws_s3_bucket_object.canary_script.bucket
  s3_key                    = aws_s3_bucket_object.canary_script.key
  artifact_s3_location      = "s3://${aws_s3_bucket.canary_bucket.id}/"
  execution_role_arn        = aws_iam_role.canary.arn
  handler                   = "apiCanaryBlueprint.handler"
  runtime_version           = "syn-nodejs-puppeteer-3.3"

  schedule {
    expression = "rate(1 hour)"
  }

  run_config {
    active_tracing      = local.canary_active_tracing_enabled
    memory_in_mb        = local.canary_memory_limit_in_mb
    timeout_in_seconds  = local.canary_timeout_in_seconds
  }
}

resource "null_resource" "add_environment_variables_to_canary" {
  # Run this command again whenever any of the run-config parameters change
  triggers = {
    canary_active_tracing_enabled = local.canary_active_tracing_enabled
    canary_memory_limit_in_mb     = local.canary_memory_limit_in_mb
    canary_timeout_in_seconds     = local.canary_timeout_in_seconds
    # Trigger values must be strings (or implicitly coerced into strings, like bools), so turn env vars into a string like FOO=bar,FIZZ=buzz
    canary_environment_variables  = join(",", [ for key, value in local.canary_environment_variables: "${key}=${value}" ])
  }
  provisioner "local-exec" {
    command = local.set_canary_run_config_command
  }

  depends_on = [ aws_synthetics_canary.healthchecks ]
}

@github-actions
Copy link

This functionality has been released in v4.5.0 of the Terraform AWS Provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.

For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template. Thank you!

@github-actions
Copy link

github-actions bot commented May 9, 2022

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement Requests to existing resources that expand the functionality or scope. service/synthetics Issues and PRs that pertain to the synthetics service. upstream Addresses functionality related to the cloud provider.
Projects
None yet