Terraform-provider-aws: Handling of aws_lambda_alias on aws_lambda_function publish true

Created on 30 Jan 2018  ·  9Comments  ·  Source: hashicorp/terraform-provider-aws

Terraform Version

Terraform v0.11.2
AWS Provider Plugin v1.8.0

Affected Resource(s)

  • aws_lambda_function
  • aws_lambda_alias

Terraform Configuration Files

variable "lambda_version" {
  default = "MASTER-120"
}

resource "aws_lambda_function" "lambda" {
  function_name = "sample-lambda"
  ...
  publish = true
  s3_key = "sample-lambda-${var.lambda_version}.jar"
}

resource "aws_lambda_alias" "active" {
  name             = "ACTIVE"
  function_name    = "${aws_lambda_function.lambda.arn}"
  function_version = "${aws_lambda_function.lambda.version}"
}

resource "aws_lambda_alias" "version" {
  name             = "${var.lambda_version}"
  function_name    = "${aws_lambda_function.lambda.arn}"
  function_version = "${aws_lambda_function.lambda.version}"
}

1st iteration plan + apply

The resources are created already. We just change the lambda_version variable.

Plan Output

  ~ aws_lambda_alias.version
      name:   "MASTER-119" => "MASTER-120"

  ~ aws_lambda_function.lambda
      s3_key: "sample-lambda-MASTER-119.jar" => "sample-lambda-MASTER-120.jar"

Panic Output

* aws_lambda_alias.version: aws_lambda_alias.version: diffs didn't match during apply. This is a bug with Terraform and should be reported as a GitHub Issue.

    Terraform Version: 0.11.2
    Resource ID: aws_lambda_alias.version
    Mismatch reason: extra attributes: function_version
    Diff One (usually from plan): *terraform.InstanceDiff{mu:sync.Mutex{state:0, sema:0x0}, Attributes:map[string]*terraform.ResourceAttrDiff{"name":*terraform.ResourceAttrDiff{Old:"MASTER-119", New:"MASTER-120", NewComputed:false, NewRemoved:false, NewExtra:interface {}(nil), RequiresNew:false, Sensitive:false, Type:0x0}}, Destroy:false, DestroyDeposed:false, DestroyTainted:false, Meta:map[string]interface {}(nil)}
    Diff Two (usually from apply): *terraform.InstanceDiff{mu:sync.Mutex{state:0, sema:0x0}, Attributes:map[string]*terraform.ResourceAttrDiff{"function_version":*terraform.ResourceAttrDiff{Old:"19", New:"20", NewComputed:false, NewRemoved:false, NewExtra:interface {}(nil), RequiresNew:false, Sensitive:false, Type:0x0}, "name":*terraform.ResourceAttrDiff{Old:"MASTER-119", New:"MASTER-120", NewComputed:false, NewRemoved:false, NewExtra:interface {}(nil), RequiresNew:false, Sensitive:false, Type:0x0}}, Destroy:false, DestroyDeposed:false, DestroyTainted:false, Meta:map[string]interface {}(nil)}

2nd iteration plan + apply

Plan Output

  ~ aws_lambda_alias.active
      function_version: "19" => "20"

  ~ aws_lambda_alias.version
      function_version: "19" => "20"
      name:             "MASTER-119" => "MASTER-120"

Panic Output

* aws_lambda_alias.version: 1 error(s) occurred:

* aws_lambda_alias.version: Error updating Lambda alias: ResourceNotFoundException: Alias not found: arn:aws:lambda:us-east-1:999999999999:function:sample-lambda:MASTER-120
        status code: 404, request id: b4c1f26c-01f3-11e8-ab3c-89f62313e37f

3rd iteration plan + apply

Plan Output

  + aws_lambda_alias.version
      id:               <computed>
      arn:              <computed>
      function_name:    "arn:aws:lambda:us-east-1:999999999999:function:sample-lambda"
      function_version: "20"
      name:             "MASTER-120"

Panic Output

None

Expected Behavior

aws_lambda_function should mark the version attribute as changing when publish = true is set, and aws_lambda_alias should wait with the computation of function_version until aws_lambda_function resource returns the new version attribute (see 1nd iteration).

aws_lambda_alias cannot handle this as an in-place update, as the resource ARN changes (see 2nd iteration).

We expect the plan output to look like this in first place:

-/+ aws_lambda_alias.active (new resource required)
      id:               <computed>
      arn:              <computed>
      function_name:    "arn:aws:lambda:us-east-1:999999999999:function:sample-lambda"
      function_version: <computed> (forces new resource)
      name:             <computed>

-/+ aws_lambda_alias.version (new resource required)
      id:               <computed>
      arn:              <computed>
      function_name:    "arn:aws:lambda:us-east-1:999999999999:function:sample-lambda"
      function_version: <computed> (forces new resource)
      name:             <computed>

  ~ aws_lambda_function.lambda
      version:          "19" => <computed>
      s3_key:           "sample-lambda-MASTER-119.jar" => "sample-lambda-MASTER-120.jar"

aws_lambda_alias should be able to (optionally) treat aliases like tags - never destroy, just create new ones.
Assuming it plans it as a resource replacement, we could achieve that with lifecycle { prevent_destroy = true }.

Actual Behavior

Shown in plan and debug output above.
We always need to apply thrice.

Steps to Reproduce

  1. Create and apply a lambda and tag it with aliases according to the scheme shown at the top.
  2. Change the lambda_version variable.
  3. terraform apply
bug serviclambda

Most helpful comment

Thanks to @mdlavin the fix for this has been merged into master and will be released in v1.10.0 of the AWS provider, likely later today or Monday. 🎉

All 9 comments

Thanks @visit1985 for writing this up with the explanation, we run into the same problem.

I believe that this problem is fixed with the pending PR #3032

Thanks to @mdlavin the fix for this has been merged into master and will be released in v1.10.0 of the AWS provider, likely later today or Monday. 🎉

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

@bflad #3032 fixes it partially. There is still the issue, that terraform tries to change the alias name as an in-place update.

  ~ lambda.aws_lambda_alias.active
      function_version: "22" => "${aws_lambda_function.lambda.version}"

  ~ lambda.aws_lambda_alias.version
      function_version: "22" => "${aws_lambda_function.lambda.version}"
      name:             "MASTER-120" => "MASTER-121"

  ~ lambda.aws_lambda_function.lambda
      last_modified:    "2018-03-09T09:37:11.524+0000" => <computed>
      qualified_arn:    "arn:aws:lambda:us-east-1:999999999999:function:sample-lambda:22" => <computed>
      s3_key:           "sample-lambda-MASTER-120.jar" => "sample-lambda-MASTER-121.jar"
      version:          "22" => <computed>
* lambda.aws_lambda_alias.version: 1 error(s) occurred:

* aws_lambda_alias.version: Error updating Lambda alias: ResourceNotFoundException: Alias not found: arn:aws:lambda:us-east-1:999999999999:function:sample-lambda:MASTER-121
        status code: 404, request id: ca3401b9-237d-11e8-8e0e-05a5757ee33f

Shall I open a new issue for that?

@bflad ?

@visit1985 did you end up opening a new issue for what you described? I can also see the same behaviour - surely this shouldn't be an update in-place?

Please open a separate new issue, thanks 👍

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 feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

Was this page helpful?
0 / 5 - 0 ratings