hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.85k stars 9.19k forks source link

[Bug]: panic: runtime error: invalid memory address or nil pointer dereference #29489

Open malinoff opened 1 year ago

malinoff commented 1 year ago

Terraform Core Version

1.3.9

AWS Provider Version

4.54.0

Affected Resource(s)

Expected Behavior

Terraform is able to import existing ECR repository and its lifecycle policy.

Actual Behavior

Terraform crashed.

Relevant Error/Panic Output Snippet

Stack trace from the terraform-provider-aws_v4.54.0_x5 plugin:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x8 pc=0x10a3d961c]

goroutine 797 [running]:
github.com/hashicorp/terraform-provider-aws/internal/service/ecr.(*lifecyclePolicyRuleSelection).reduce(0x0)
    github.com/hashicorp/terraform-provider-aws/internal/service/ecr/lifecycle_policy.go:220 +0x1c
github.com/hashicorp/terraform-provider-aws/internal/service/ecr.(*lifecyclePolicy).reduce(0x14004c2f518)
    github.com/hashicorp/terraform-provider-aws/internal/service/ecr/lifecycle_policy.go:215 +0x8c
github.com/hashicorp/terraform-provider-aws/internal/service/ecr.equivalentLifecyclePolicyJSON({0x0, 0x0}, {0x1400482da80, 0x40})
    github.com/hashicorp/terraform-provider-aws/internal/service/ecr/lifecycle_policy.go:256 +0x15c
github.com/hashicorp/terraform-provider-aws/internal/service/ecr.ResourceLifecyclePolicy.func1({0x14005008a48?, 0x10b11eb16?}, {0x0?, 0x140010e7900?}, {0x1400482da80?, 0x10f747b90?}, 0x1400484b080?)
    github.com/hashicorp/terraform-provider-aws/internal/service/ecr/lifecycle_policy.go:47 +0x34
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.schemaMap.diff(0x14005008eb8?, {0x10f73b740, 0x1400397d5f0}, {0x10b11eb16, 0x6}, 0x140010e7900, 0x1400484b000, {0x10f747b90?, 0x1400484b080}, 0x0)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.24.1/helper/schema/schema.go:1144 +0x274
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.schemaMap.Diff(0x140010b7bc0, {0x10f73b740, 0x1400397d5f0}, 0x14004c24f70, 0x1400397da70, 0x0, {0x10f5fa360, 0x1400186b000}, 0x0)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.24.1/helper/schema/schema.go:679 +0x2a0
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).SimpleDiff(0x10f73c5e8?, {0x10f73b740?, 0x1400397d5f0?}, 0x14004c24f70, 0x10da64600?, {0x10f5fa360?, 0x1400186b000?})
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.24.1/helper/schema/resource.go:890 +0x50
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).PlanResourceChange(0x1400000c090, {0x10f73b740?, 0x1400397d4d0?}, 0x14003201c20)
    github.com/hashicorp/terraform-plugin-sdk/v2@v2.24.1/helper/schema/grpc_provider.go:741 +0x838
github.com/hashicorp/terraform-plugin-mux/tf5muxserver.muxServer.PlanResourceChange({0x140030f1860, 0x140030f18c0, {0x1400493e860, 0x2, 0x2}, {0x0, 0x0, 0x0}, {0x0, 0x0, ...}, ...}, ...)
    github.com/hashicorp/terraform-plugin-mux@v0.8.0/tf5muxserver/mux_server_PlanResourceChange.go:27 +0xdc
github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server.(*server).PlanResourceChange(0x14001de20a0, {0x10f73b740?, 0x1400397c150?}, 0x140019b76c0)
    github.com/hashicorp/terraform-plugin-go@v0.14.3/tfprotov5/tf5server/server.go:783 +0x3b8
github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_PlanResourceChange_Handler({0x10f317900?, 0x14001de20a0}, {0x10f73b740, 0x1400397c150}, 0x140019b75e0, 0x0)
    github.com/hashicorp/terraform-plugin-go@v0.14.3/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:367 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0x140044781e0, {0x10f74a600, 0x14003830680}, 0x14004c41680, 0x140049eb650, 0x115c90aa8, 0x0)
    google.golang.org/grpc@v1.53.0/server.go:1336 +0xb7c
google.golang.org/grpc.(*Server).handleStream(0x140044781e0, {0x10f74a600, 0x14003830680}, 0x14004c41680, 0x0)
    google.golang.org/grpc@v1.53.0/server.go:1704 +0x82c
google.golang.org/grpc.(*Server).serveStreams.func1.2()
    google.golang.org/grpc@v1.53.0/server.go:965 +0x84
created by google.golang.org/grpc.(*Server).serveStreams.func1
    google.golang.org/grpc@v1.53.0/server.go:963 +0x290

Error: The terraform-provider-aws_v4.54.0_x5 plugin crashed!

Terraform Configuration Files

The following data was added to the state file (replaced sensitive values with <>):

    {
      "mode": "managed",
      "type": "aws_ecr_repository",
      "name": "main",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "arn": "arn:aws:ecr:<region>:<account_id>:repository/myrepo",
            "encryption_configuration": [
              {
                "encryption_type": "AES256",
                "kms_key": ""
              }
            ],
            "force_delete": null,
            "id": "myrepo",
            "image_scanning_configuration": [
              {
                "scan_on_push": false
              }
            ],
            "image_tag_mutability": "MUTABLE",
            "name": "myrepo",
            "registry_id": "<account_id>",
            "repository_url": "<account_id>.dkr.ecr.<region>.amazonaws.com/myrepo",
            "tags": {},
            "tags_all": {},
            "timeouts": {
              "delete": null
            }
          },
          "sensitive_attributes": [],
          "private": "<snip>"
        }
      ]
    },

Steps to Reproduce

I'm trying to import existing resources. I've specified the following resource definitions:

resource "aws_ecr_repository" "main" {
  name = "myrepo"
}

resource "aws_ecr_lifecycle_policy" "main" {
  repository = aws_ecr_repository.main.name
  policy     = <<EOF
{
  "rules": [
    {
      "rulePriority": 1,
      "description": "Remove old images"
    }
  ]
}
EOF
}

Then I've imported the repository with the following command:

terraform import aws_ecr_repository.main myrepo

Then I executed terraform plan to see the plan. I expected to either see an error (something about the lifecycle policy being invalid/unavailable/unmanaged) or a plan to add this lifecycle policy (since I haven't imported it yet).

Debug Output

No response

Panic Output

No response

Important Factoids

No response

References

No response

Would you like to implement a fix?

None

github-actions[bot] commented 1 year ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

malinoff commented 1 year ago

Removing aws_ecr_lifecycle_policy.main from the .tf file results in a plan being successfully produced.

malinoff commented 1 year ago

Looks like it crashes only because the lifecycle policy is malformed. Same crash happened when I imported the policy to the state file. Either removing the policy resource or specifying a correct policy works.

Audiopolis commented 3 days ago

Also experiencing this. Still haven't determined what a correct policy looks like, but the error messages were not very helpful. The only hint was that it started happening after adding the lifecycle policy.

Edit: The following succeeded in applying:

resource "aws_ecr_repository" "api" {
  name = "api"
  image_tag_mutability = "MUTABLE"

  image_scanning_configuration {
    scan_on_push = true
  }
}

resource "aws_ecr_repository" "nginx" {
  name = "nginx"
  image_tag_mutability = "MUTABLE"

  image_scanning_configuration {
      scan_on_push = true
  }
}

data "aws_ecr_lifecycle_policy_document" "limit_images" {
  rule {
    priority = 1
    description = "Keep only the most recent untagged image"
    selection {
      count_type = "imageCountMoreThan"
      count_number = 1
      tag_status = "untagged"
    }
    action {
      type = "expire"
    }
  }

  rule {
    priority = 2
    description = "Keep only the 5 most recent tagged images"
    selection {
      count_type = "imageCountMoreThan"
      count_number = 5
      tag_status = "tagged"
      tag_pattern_list = ["*"]
    }
  }
}

resource "aws_ecr_lifecycle_policy" "api" {
  repository = aws_ecr_repository.api.name
  policy = data.aws_ecr_lifecycle_policy_document.limit_images.json
}

resource "aws_ecr_lifecycle_policy" "nginx" {
  repository = aws_ecr_repository.nginx.name
  policy = data.aws_ecr_lifecycle_policy_document.limit_images.json
}

Terraform does not tell you that tag_pattern_list is required when tag_status = "tagged". I have not confirmed that this works as intended, just that it applied successfully.