Importing terraform aws_iam_policy

Viewed 2966

I'm trying to import a terraform aws_iam_policy that gets automatically added by automation I don't own. The import seems to work but once I run a terraform plan I get the following error

* aws_iam_policy.mypolicy1: "policy": required field is not set

I'm running the terraform import as follows.

terraform import aws_iam_policy.mypolicy1 <myarn>

Here is my relevant terraform config

resource "aws_iam_policy" "mypolicy1" {

}

resource "aws_iam_role_policy_attachment" "mypolicy1_attachment`" {
    role       = "${aws_iam_role.myrole1.name}"
    policy_arn = "${aws_iam_policy.mypolicy1.arn}"
}

resource "aws_iam_role" "myrole1" {
     name = "myrole1"
     assume_role_policy = "${file("../policies/ecs-role.json")}"
}

I double checked that the terraform.tfstate included the policy i'm trying to import. Is there something else I'm missing here?

2 Answers

I finally found a relatively elegant, and universal work-around to address Amazon's poor implementation of the import IAM policy capability. The solution does NOT require that you reverse engineer Amazon, or anybody else's, implementation of the "aws_iam_policy" resource that you want to import.

There are two steps.

  1. Create an aws_iam_policy resource definition that has a "lifecycle" argument, with an ignore_changes list. There are three fields in the aws_iam_policy resource that will trigger a replacement: policy, description and path. Add these three fields to the ignore_changes list.
  2. Import the external IAM policy, and attach it to the resource definition that you created in your resource file.

Resource file (ex: static-resources.tf)

resource "aws_iam_policy" "MyLambdaVPCAccessExecutionRole" {
  lifecycle {
    prevent_destroy = true
    ignore_changes = [policy, path, description]
  }
  policy = jsonencode({})
}

Import Statement: Using the arn of the IAM policy that you want to import, import the policy and attach it to your resource definition.

terraform import aws_iam_policy.MyLambdaVPCAccessExecutionRole arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole

The magic is the fields that you need to add to the ignore_changes list, and adding a place-holder for the required "policy" argument. Since this is a required field, Terraform won't let you proceed without it, even though this is one of the fields that you told Terraform to ignore any changes to.

Note: If you use modules, you will need to add "module.." to the front on your resource reference. For example

terraform import module.static.aws_iam_policy.MyLambdaVPCAccessExecutionRole arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
Related