Terraform - 尽管已在同一文件中声明,但未找到变量的资源

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

Terraform 找不到在引用所在的同一文件中声明的资源。

似乎是这一行引起了问题:role_arn = "${aws_iam_role.newsapi_lambda_codepipeline.arn}"。它找不到声明为 resource "aws_iam_role" "newsapi_lambda_codepipeline" { ... }.

newsapi_lambda_codepipeline

这是我的 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"
      }
    }
  }
}

执行后 terraform apply 我得到:

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'

我不明白为什么会这样。我已经 aws_iam_role.newsapi_lambda_codepipeline 声明了,不是吗?

我认为您的角色声明可能有点错误。并且 terraform 无法为此生成 arn,因此未找到。

看来您还需要创建 resource "aws_iam_role_policy"。参见 https://www.terraform.io/docs/providers/aws/r/codepipeline.html 有点不清楚为什么需要拆分。

如果不是这种情况,请告诉我,我会尝试 运行 自己测试代码。

对于那些遇到 aws_ecs_task_definition 找不到 aws_ecs_task_definition.XXX.arn 变量的问题的人,很有可能您的 JSON 格式不正确。这是我为解决问题所做的工作

  • 将你的行替换为 task_definition = "[]"
  • 运行 terraform plan

此时你应该得到一个错误。例如,我得到了

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

在这种情况下,我在 template_file 中引用了 memSize 并且它没有隐式转换为 int64,因此出现错误。

我把"memoryReservation": "${mem_size}"改成了"memoryReservation": ${mem_size},去掉了task_definition占位符,一切顺利。

由于问题的标题很笼统,所以我找到了这个 link。

鉴于存在 something wrong with the resource which was not found and hence it is not getting created

,我能够找到问题所在

在我的例子中,这是一个变量没有在 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

为了帮助调查此类问题,您可以 运行 有针对性地 terraform plan。 在我的例子中(对来自自定义 AWS VPC 模块的 CIDR 块的错误配置引用),在 运行ning

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

Terraform 实际上提供了明确的错误消息,说明我这次到底做错了什么。 希望对您有所帮助:)