Defozo
Defozo

Reputation: 3092

Terraform - Resource not found for variable despite having it declared in the same file

Terraform can't find a resource which is declared in the same file where the reference is.

It seems that this line is causing trouble: role_arn = "${aws_iam_role.newsapi_lambda_codepipeline.arn}". It can't find newsapi_lambda_codepipeline which is declared as resource "aws_iam_role" "newsapi_lambda_codepipeline" { ... }.

This is my main.tf:

resource "aws_s3_bucket" "newsapi_lambda_builds" {
  bucket = "newsapi-lambda-builds"
  acl    = "private"
}

resource "aws_iam_role" "newsapi_lambda_codebuild" {
  name = "newsapi-lambda-codebuild"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:GetBucketVersioning"
      ],
      "Resource": "arn:aws:s3:::newsapi_lambda_builds",
      "Effect": "Allow"
    },
    {
      "Action": [
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::newsapi_lambda_builds"
      ],
      "Effect": "Allow"
    },
    {
      "Action": [
        "lambda:invokefunction",
        "lambda:listfunctions"
      ],
      "Resource": "*",
      "Effect": "Allow"
    },
    {
      "Effect": "Allow",
      "Resource": [
        "*"
      ],
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ]
    }
  ]
}
EOF
}
resource "aws_iam_role" "newsapi_lambda_codepipeline" {
  name = "newsapi-lambda-codepipeline"

  assume_role_policy = <<EOF
{
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "codepipeline.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    },
    {
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:GetBucketVersioning"
      ],
      "Resource": "${aws_s3_bucket.newsapi_lambda_builds.arn}",
      "Resource": "${aws_s3_bucket.newsapi_lambda_builds.arn}/*"
      "Effect": "Allow"
    },
    {
      "Action": [
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::newsapi_lambda_builds"
      ],
      "Effect": "Allow"
    },
    {
      "Effect": "Allow",
      "Action": [
        "codebuild:BatchGetBuilds",
        "codebuild:StartBuild"
      ],
      "Resource": "*"
    }
  ],
  "Version": "2012-10-17"
}
EOF
}


resource "aws_codepipeline" "newsapi_lambda" {
  name     = "newsapi-lambda"
  role_arn = "${aws_iam_role.newsapi_lambda_codepipeline.arn}"

  artifact_store {
    location = "${aws_s3_bucket.newsapi_lambda_builds.bucket}"
    type     = "S3"
  }

  stage {
    name = "Source"

    action {
      name             = "Source"
      category         = "Source"
      owner            = "ThirdParty"
      provider         = "GitHub"
      version          = "1"
      output_artifacts = ["newsapi_lambda"]

      configuration {
        Owner      = "Defozo"
        Repo       = "traceitfor.me_newsapi_lambda"
        Branch     = "master"
      }
    }
  }

  stage {
    name = "Build"

    action {
      name            = "Build"
      category        = "Build"
      owner           = "AWS"
      provider        = "CodeBuild"
      input_artifacts = ["newsapi_lambda"]
      version         = "1"
      role_arn = "${aws_iam_role.newsapi_lambda_codebuild.arn}"

      configuration {
        ProjectName = "newsapi-lambda"
      }
    }
  }
}

After executing terraform apply I get:

Error: Error running plan: 1 error(s) occurred:

* aws_codepipeline.newsapi_lambda: 1 error(s) occurred:

* aws_codepipeline.newsapi_lambda: Resource 'aws_iam_role.newsapi_lambda_codepipeline' not found for variable 'aws_iam_role.newsapi_lambda_codepipeline.arn'

I don't understand why that happens. I have aws_iam_role.newsapi_lambda_codepipeline declared, haven't I?

Upvotes: 8

Views: 20515

Answers (4)

Karol Małyszko
Karol Małyszko

Reputation: 31

To help out with investigating such issues, you can run targeted terraform plan. In my case (misconfigured reference to CIDR block from custom AWS VPC module), after running

terraform plan --target aws_security_group.something-or-other

Terraform actually provided clear error message on what exactly i did wrong this time. Hope it helps :)

Upvotes: 3

rahuljain1311
rahuljain1311

Reputation: 2160

Since the title of the problem is pretty generic, I landed on this link.

I was able to find the problem, given the fact that there is something wrong with the resource which was not found and hence it is not getting created

In my case it was a variable not getting referenced correctly in aws_cloudwatch_event_rule "event_pattern" key

    event_pattern = <<PATTERN
{
  "source": [
    "aws.ecs"
  ],
  "detail-type": [
    "ECS Task State Change"
  ],
  "detail": {
    "lastStatus": [
        "STOPPED"
    ],
    "desiredStatus": [
        "RUNNING"
    ],
    "clusterArn": [
      ${aws_ecs_cluster.main.arn}
    ]
  }
}
PATTERN

Upvotes: 0

wonton
wonton

Reputation: 8247

For those experiencing an issue with aws_ecs_task_definition not finding a variable for the aws_ecs_task_definition.XXX.arn, there's a good chance your JSON came out malformed. Here's what I did to remedy my issue

  • Replace your line with task_definition = "[]"
  • Run terraform plan

At this point you should get an error. For example, I got

module.tf.aws_ecs_task_definition.sandbox: ECS Task Definition container_definitions is invalid: Error decoding JSON: json: cannot unmarshal string into Go struct field ContainerDefinition.MemoryReservation of type int64

In this case, I had quoted memSize in my template_file and it didn't implicitly convert to int64, hence an error.

I changed "memoryReservation": "${mem_size}" to "memoryReservation": ${mem_size}, removed the task_definition placeholder, and everything went smoothly.

Upvotes: 10

Jenninha
Jenninha

Reputation: 1377

I believe your role declaration could be slightly wrong. And terraform was not able to generate an arn for that, therefore not found.

It looks like you also need to create resource "aws_iam_role_policy". See https://www.terraform.io/docs/providers/aws/r/codepipeline.html It's a bit unclear why you'd need to split.

If this is not the case, let me know and I'll try to run the code myself to test.

Upvotes: 7

Related Questions