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

error creating CloudFront Distribution: InvalidLambdaFunctionAssociation: The function ARN must reference a specific function version. (The ARN must end with the version number.) ARN: arn:aws:lambda:eu-west-1:128523434494:function:security-headers-terraform-new:$LATEST #21238

Open
ghost opened this issue Oct 11, 2021 · 11 comments
Labels
bug Addresses a defect in current functionality. service/cloudfront Issues and PRs that pertain to the cloudfront service.

Comments

@ghost
Copy link

ghost commented Oct 11, 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

Terraform CLI and Terraform AWS Provider Version

Affected Resource(s)

  • aws_XXXXX

Terraform Configuration Files

Please include all Terraform configurations required to reproduce the bug. Bug reports without a functional reproduction may be closed without investigation.

# Copy-paste your Terraform configurations here - for large Terraform configs,
# please use a service like Dropbox and share a link to the ZIP file. For
# security, you can also encrypt the files using our GPG public key: https://keybase.io/hashicorp

Debug Output

Panic Output

Expected Behavior

Actual Behavior

Steps to Reproduce

  1. terraform apply

Important Factoids

References

  • #0000
@github-actions github-actions bot added the needs-triage Waiting for first response or review from a maintainer. label Oct 11, 2021
@ghost
Copy link
Author

ghost commented Oct 11, 2021

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "3.61.0"
    }
  }
}

provider "aws"{
    region ="eu-west-1"
}



resource "aws_s3_bucket" "creattestbucketshreyaaftp"{
  bucket="rtedd"
  acl="private"
  force_destroy = true

}

resource "aws_iam_role" "iam_for_lambda" {
  name = "iam_for_lambda"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}


resource "aws_lambda_function" "testlambda56rty"{

function_name = "security-headers-terraform-new"
filename="aftp-qa-cloudfront-security-headers.zip"
role= aws_iam_role.iam_for_lambda.arn
 runtime = "nodejs12.x"
 handler       = "index.js"
 
}

resource "aws_cloudfront_origin_access_identity" "newOAI" {
  comment = "OAI User"
}


locals {
  s3_origin_id = "S3AFTPOrigin"
}

resource "aws_cloudfront_distribution" "s3-distribution"{
origin{
    domain_name=aws_s3_bucket.creattestbucketshreyaaftp.bucket_regional_domain_name
    origin_id=local.s3_origin_id
    s3_origin_config {
      origin_access_identity = aws_cloudfront_origin_access_identity.newOAI.cloudfront_access_identity_path
    }

}
enabled             = true
is_ipv6_enabled     = true
default_root_object = "index.html"
aliases=["examplerrr.futuretalentplatform.com"]


default_cache_behavior {
    allowed_methods  = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = local.s3_origin_id

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }

      lambda_function_association {
      event_type   = "viewer-request"
      lambda_arn   = aws_lambda_function.testlambda56rty.qualified_arn
      include_body = false
    }


    viewer_protocol_policy = "allow-all"
    min_ttl                = 0
    default_ttl            = 3600
    max_ttl                = 86400
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
      
    }
  }

    viewer_certificate {
    acm_certificate_arn = "arn:aws:acm:us-east-1:128523434494:certificate/cf938fd1-f6e5-400c-8bf7-b67cc5a2d160"
    ssl_support_method  = "sni-only"
  }
  

}

data "aws_iam_policy_document" "s3_policy" {
 statement {
  actions   = ["s3:GetObject"]
   resources = ["${aws_s3_bucket.creattestbucketshreyaaftp.arn}/*"]

   principals {
     type        = "AWS"

     identifiers = [aws_cloudfront_origin_access_identity.newOAI.iam_arn]
  }
 }
}

resource "aws_s3_bucket_policy" "s3policyforOAI" {
  bucket = aws_s3_bucket.creattestbucketshreyaaftp.id
  policy = data.aws_iam_policy_document.s3_policy.json
}

This is my terraform script. Can anyone please help me with the error.

@ewbankkit ewbankkit added the service/cloudfront Issues and PRs that pertain to the cloudfront service. label Oct 11, 2021
@justinretzolk
Copy link
Member

Hey @shreyashi1209 👋 Thank you for taking the time to file this issue. In looking over it, I noticed something that I think might make the difference here. Looking at the outputs for the aws_lambda_function resource, I see that qualified_arn says:

ARN identifying your Lambda Function Version (if versioning is enabled via publish = true).

With that in mind, I reviewed the AWS documentation around lambda function versions, which says:

You can use a qualified or an unqualified ARN in all relevant API operations. However, you can't use an unqualified ARN to create an alias.

If you decide not to publish function versions, you can invoke the function using either the qualified or unqualified ARN in your event source mapping. When you invoke a function using an unqualified ARN, Lambda implicitly invokes $LATEST.

With that information, my read is that there's two possible solutions for this:

  1. Enabling versioning for the Lambda function by adding publish = true to the resource definition
  2. Use the aws_lambda_function.testlambda56rty.arn rather than aws_lambda_function.testlambda56rty.qualified_arn in order to get the ARN of the Lambda function

@justinretzolk justinretzolk added waiting-response Maintainers are waiting on response from community or contributor. and removed needs-triage Waiting for first response or review from a maintainer. labels Oct 12, 2021
@McTristan
Copy link

We are seeing the same problems. However, publish = true is already set on our lambda edge function and using .arn instead of qualified_arn results in an arn without the "$LATEST" tag at the end - however the error message remains the same.

@github-actions github-actions bot removed the waiting-response Maintainers are waiting on response from community or contributor. label Oct 19, 2021
@justinretzolk justinretzolk added the bug Addresses a defect in current functionality. label Oct 22, 2021
@justinretzolk
Copy link
Member

Hey @McTristan 👋 Thank you for confirming that. With that information in mind, I've marked this as a bug so that we can take a look into it as soon as time allows.

@dcorrea777
Copy link

I had the same problem but @justinretzolk solution worked for me

my code looked like this

lambda_function_association {
    event_type   = "viewer-request"
    lambda_arn   = "${aws_lambda_function.my_resource.arn}:${aws_lambda_function.my_resource.version}"
    include_body = false
}

I also set the publish parameter to true in my lambda function

@MrVJTod
Copy link

MrVJTod commented Jul 25, 2022

this is a problem for me as well, but because I'm using my lambda across several cloudfront stacks, I'm unable to define the lambda with the cloudfront.

I tried to define data aws_lambda_function references to the functions, but the function version shows as "$LATEST", not the actual latest version. From the source stack, I can see the actual version in the resource object.

my states are all in s3 and I was able to workaround this by using "terraform_remote_state" references to all of my lambda functions

I did need to define Output values for all of the data I wanted to share, but this workaround is working for me.

@justinretzolk
Copy link
Member

Hi all 👋 Thank you all for confirming that the above information helped! With that in mind, we'll close this issue for now. If you feel we've done this in error, please do let us know, or open a new issue with additional information.

@MrVJTod
Copy link

MrVJTod commented Jul 25, 2022

it would be nice if this could be fixed proper so that workarounds were not necessary. I was wasting a bunch of time trying to get aws_lambda_function DATA references to work until I stumbled across the remote state option. I originally ignored that option because I didn't realize it would work with S3 storage.

@justinretzolk justinretzolk reopened this Jul 25, 2022
@justinretzolk
Copy link
Member

Hey @MrVJTod -- I think that's a totally valid ask, so I'll re-open the issue so that we can look into this a bit more.

@laksh-parab
Copy link

laksh-parab commented Aug 24, 2022

it looks like if the lambda is already published and then in another stack (where you create cloudfront) if you use data to get qualified_arn then data source returns arn with $LATEST but not with version.

-- this will be separate apply from lambda creation. 
data "aws_lambda_function" "lambda_edge" {
  function_name = "myfunction"     
}

resource "aws_cloudfront_distribution" "my_distribution" {
..
..
  lambda_function_association {
      event_type   = "origin-request"
      lambda_arn   = "${data.aws_lambda_function.lambda_edge.qualified_arn}" -- this returns arn without version
      include_body = false
    }
}

However if you create cloudfront and lambda in the same stack and then use qualified_arn of the resource then it returns arn with version number

--this will be in the same apply where you create lambda and cloudfront together

resource "aws_lambda_function" "this" {
  function_name = "myfunction"     
}

resource "aws_cloudfront_distribution" "my_distribution" {
..
..
  lambda_function_association {
      event_type   = "origin-request"
      lambda_arn   = "${aws_lambda_function.this.qualified_arn}" -- this returns arn with version
      include_body = false
    }
}

@aprilmintacpineda
Copy link

The real problem here is that lambda@edge requires us to specify the specific version that cloudfront will use, so arn like arn:aws:lambda:{region}:{account-id}:function:{function-name} is not gonna work, also we cannot use aliases so arn like arn:aws:lambda:{region}:{account-id}:function:{function-name}:$latest is also not gonna work.

Here's what needs to be done:

  1. On the aws_lambda_function resource, set publish = true
  2. On the aws_cloudfront_distribution resource, set lambda_arn = aws_lambda_function.<lambda_function_name>.qualified_arn

This will result to an arn that looks like this arn:aws:lambda:{region}:{account-id}:function:{function-name}:{version-number} where version-number will always refer to the latest version number.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Addresses a defect in current functionality. service/cloudfront Issues and PRs that pertain to the cloudfront service.
Projects
None yet
Development

No branches or pull requests

7 participants