【问题标题】:Correct terraform syntax for adding permissions to AWS Lambda为 AWS Lambda 添加权限的正确 terraform 语法
【发布时间】:2019-10-09 04:53:23
【问题描述】:

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

  1. 可以从我也在 Terraform 中创建的 API 网关调用 Lambda
  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
}

我看到下面的 sn-p 允许 Lambda 写入 CloudWatch。我正在尝试结合这些 sn-ps 来获得所有权限,但我无法做到正确。将所有这些权限授予角色的正确语法是什么?

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

【问题讨论】:

    标签: aws-lambda terraform


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:
      • 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 代码

      【讨论】:

        【解决方案3】:

        a previous answer 中,我写了一些关于 IAM 角色如何工作以及什么是“承担角色策略”的背景信息。我将假设此答案中的背景信息。

        您在resource "aws_iam_role" "my_lambda_execution_role" 块中的assume_role_policy 参数中提供的策略是管理允许哪些用户和服务“担任”此角色的策略。在这种情况下,您允许 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 资源中引用角色时,您必须使用 @987654328 @ 告诉 Terraform 在策略可用之前必须完成策略附件:

        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,则存在在角色附加完成之前创建并执行函数的风险,因此您的函数的初始执行可能无法写入其日志。如果您的函数在创建后没有立即执行,那么这在实践中可能不会发生,但最好包含 depends_on 以确保其完整并让未来的维护人员知道该角色的访问策略也是 对 Lambda 函数的功能很重要。

        【讨论】:

          猜你喜欢
          • 2020-01-08
          • 1970-01-01
          • 2019-10-14
          • 2023-03-15
          • 1970-01-01
          • 2017-08-20
          • 2021-11-14
          • 1970-01-01
          • 2021-11-17
          相关资源
          最近更新 更多