正确的Terraform语法,用于向AWS Lambda添加权限

时间:2019-10-08 11:30:04

标签: aws-lambda terraform

我正在学习Terraform,并且试图获取正确的语法来为其指定IAM角色权限。我想要这些功能:

  1. Lambda可以从我也在Terraform中创建的API网关中调用
  2. Lambda可以写入Cloudwatch日志

我具有以下允许API网关调用Lambda的条件:

resource "aws_iam_role" "my_lambda_execution_role" {
  name = "my_lambda_execution_role"
  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": [ 
          "lambda.amazonaws.com",
          "apigateway.amazonaws.com"
        ]
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

我已经看到下面的代码片段允许Lambda写入CloudWatch。我试图结合这些代码片段来获取所有权限,但是我做不到。将所有这些权限授予角色的正确语法是什么?

{
    "Statement": [
        {
            "Action": [
                "logs:CreateLogGroup",
                 "logs:CreateLogStream",
                 "logs:PutLogEvents"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:logs:*:*:*"
        }
    ]
} 

3 个答案:

答案 0 :(得分:2)

https://www.terraform.io/docs/providers/aws/r/iam_role_policy_attachment.html

您需要创建策略,然后将其附加到您的角色。上面的链接包含一个比iam角色页面更完整的示例。

答案 1 :(得分:0)

  • IAM政策以及角色。
# iam
data "aws_iam_policy_document" "policy" {
  statement {
    sid    = ""
    effect = "Allow"

    principals {
      identifiers = ["lambda.amazonaws.com"]
      type        = "Service"
    }

    actions = ["sts:AssumeRole"]
  }
}

resource "aws_iam_role" "iam_for_lambda" {
  name               = "iam_for_lambda"
  assume_role_policy = "${data.aws_iam_policy_document.policy.json}"
}

resource "aws_iam_role_policy" "frontend_lambda_role_policy" {
  name   = "frontend-lambda-role-policy"
  role   = "${aws_iam_role.iam_for_lambda.id}"
  policy = "${data.aws_iam_policy_document.lambda_log_and_invoke_policy.json}"
}

data "aws_iam_policy_document" "lambda_log_and_invoke_policy" {

  statement {
    effect = "Allow"

    actions = [
      "logs:CreateLogGroup",
      "logs:CreateLogStream",
      "logs:PutLogEvents",
    ]

    resources = ["*"]

  }

  statement {
    effect = "Allow"

    actions = ["lambda:InvokeFunction"]

    resources = ["arn:aws:lambda:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:function:*"]
  }

}
  • 请在我的github
  • 中找到完整的Terraform代码

答案 2 :(得分:0)

a previous answer中,我写了一些有关IAM角色如何工作以及“假定角色策略”是什么的背景信息。我将以这个答案为背景信息。

您在assume_role_policy块的resource "aws_iam_role" "my_lambda_execution_role"自变量中给出的策略是控制允许哪些用户和服务“承担”该角色的策略。在这种情况下,您将允许AWS Lambda和Amazon API Gateway使用此角色授予的特权来发出请求。

但是,默认情况下,该角色根本不授予任何特权。为了解决这个问题,我们需要为该角色附加一个或多个访问策略。您在此处共享的另一个策略JSON是访问策略,要将其与角色关联,我们需要使用aws_iam_role_policy资源类型:

resource "aws_iam_role_policy" "logs" {
  name   = "lambda-logs"
  role   = aws_iam_role.my_lambda_execution_role.name
  policy = jsonencode({
    "Statement": [
      {
        "Action": [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents",
        ],
        "Effect": "Allow",
        "Resource": "arn:aws:logs:*:*:*",
      }
    ]
  })
}

通常,Terraform通过注意到上面的resource表达式之类的引用来自动推断aws_iam_role.my_lambda_execution_role块之间的依赖关系,实际上,在这种情况下,Terraform将自动确定它需要在完成角色创建之前尝试对其附加政策。

但是,Terraform 不能在此处自动看到该策略附件必须在该策略本身可操作之前完成,因此当您从API网关和Lambda资源引用该角色时,必须使用{{ 1}}告诉Terraform,该策略附件必须在该策略变得可用之前完成:

depends_on

如果不这样使用resource "aws_lambda_function" "example" { filename = "${path.module}/example.zip" function_name = "example" role = aws_iam_role.my_lambda_execution_role.arn handler = "example" # (and any other configuration you need) # Make sure the role policy is attached before trying to use the role depends_on = [aws_iam_role_policy.logs] } ,则存在在角色附加完成之前创建和执行该函数的风险,因此该函数的初始执行可能无法写入其日志。如果您的函数在创建后没有立即执行,那么在实践中可能不会发生,但是最好包含depends_on以便详尽,并让将来的人工维护人员知道角色的访问策略为