Terraform - 如何为 AWS Lambda 创建 IAM 角色并部署两者?

Rah*_*dam 9 amazon-web-services amazon-iam aws-lambda terraform

我正在学习地形。我正在尝试创建一个新的 Lambda 函数。我意识到我还需要创建一个 IAM 角色。所以我正在尝试使用 Terraform 来做这两项工作。但它不允许我创建角色。

这是我的 Terraform 文件

provider "aws" {
  profile = "default"
  region  = "eu-west-1"
}

data "aws_iam_policy" "AWSLambdaBasicExecutionRole" {
  arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

resource "aws_iam_role" "terraform_function_role" {
  name               = "terraform_function_role"
  assume_role_policy = "${data.aws_iam_policy.AWSLambdaBasicExecutionRole.policy}"
}

resource "aws_lambda_function" "terraform_function" {
  filename         = "terraform_function.zip"
  function_name    = "terraform_function"
  handler          = "index.handler"
  role             = "${aws_iam_role.terraform_function_role.id}"
  runtime          = "nodejs8.10"
  source_code_hash = "${filebase64sha256("terraform_function.zip")}"
}
Run Code Online (Sandbox Code Playgroud)

这是我得到的错误

Error creating IAM Role terraform_function_role: MalformedPolicyDocument: Has prohibited field Resource
status code: 400
Run Code Online (Sandbox Code Playgroud)

我该如何解决?

kri*_*004 8

IAM 角色的信任关系(或代入角色策略)定义了可以代入角色的资源/服务。在这里,我们没有定义 Resource 字段。因此,我们无法附加 IAM 策略或按原样使用该策略。信任关系的正确格式是:

{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Principal": {
            "Service": "lambda.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
    }]
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您账户中的所有 Lambda 函数都可以担任此角色。

您可以参考AWS 链接以获取更多示例。

编辑:基于@ydaetskcoR 评论,这是一个工作示例:

provider "aws" {
  profile = "default"
  region  = "eu-west-1"
}

data "aws_iam_policy_document" "AWSLambdaTrustPolicy" {
  statement {
    actions    = ["sts:AssumeRole"]
    effect     = "Allow"
    principals {
      type        = "Service"
      identifiers = ["lambda.amazonaws.com"]
    }
  }
}

resource "aws_iam_role" "terraform_function_role" {
  name               = "terraform_function_role"
  assume_role_policy = "${data.aws_iam_policy_document.AWSLambdaTrustPolicy.json}"
}

resource "aws_iam_role_policy_attachment" "terraform_lambda_policy" {
  role       = "${aws_iam_role.terraform_function_role.name}"
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

resource "aws_lambda_function" "terraform_function" {
  filename         = "terraform_function.zip"
  function_name    = "terraform_function"
  handler          = "index.handler"
  role             = "${aws_iam_role.terraform_function_role.arn}"
  runtime          = "nodejs8.10"
  source_code_hash = "${filebase64sha256("terraform_function.zip")}"
}
Run Code Online (Sandbox Code Playgroud)

您的代码中的更改包括以下内容:

  • 更新了代入角色权限的 aws_iam_policy_document 资源
  • 将 aws_iam_role 资源更改为使用上述策略文档
  • 创建了 aws_iam_role_policy_attachment 以附加 LambdaBasicExecution 策略(启用日志记录到 CloudWatch)
  • 更新了 aws_lambda_function 资源以使用 IAM 角色的 ARN 而不是 Id,因为 Lambda 函数需要 ARN


Tha*_*ssi 4

由于您仍处于学习阶段,我建议您改为terraform 0.12使用templatefile. 因此您不需要创建data对象。

另一件事是在创建策略时始终使用最小权限原则,这意味着您的资源(在本例中为 Lambda)只能访问其需要的内容。目前,只有 CloudWatch,但在现实世界中情况很可能并非如此。

回到您的问题,以下是您如何创建 IAM 角色、IAM 策略、最后的 IAM 策略附件(这是策略和角色之间的桥梁)以及 AssumeRolePolicy(这是其所属服务之间的信任关系)将使用它和角色本身)。我已经将它们全部提取到模板中,以便以后更容易维护。要点(为了更容易用眼睛阅读)可以在这里找到。

# iam_role
resource "aws_iam_role" "iam_role" {
  name = "iam-role"

  assume_role_policy = templatefile("${path.module}/templates/lambda-base-policy.tpl", {})
}

#content of lambda-base-policy.tpl
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}

#iam_policy
resource "aws_iam_policy" "policy" {
  name = "policy"

  policy = templatefile("${path.module}/templates/cloudwatch-policy.tpl", {})
}

#content of cloudwatch-policy.tpl
{
  "Version": "2012-10-17",
  "Statement": [
    {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
  ]
} 

#iam_policy_attachment
resource "aws_iam_policy_attachment" "policy_attachment" {
  name       = "attachment"
  roles      = ["${aws_iam_role.iam_role.name}"]
  policy_arn = "${aws_iam_policy.policy.arn}"
} 
Run Code Online (Sandbox Code Playgroud)