Правильный синтаксис terraform для добавления разрешений в AWS Lambda - PullRequest
2 голосов
/ 08 октября 2019

Я изучаю Terraform и пытаюсь получить правильный синтаксис, чтобы указать разрешения для роли IAM для него. Я хочу эти возможности:

  1. Lambda может быть вызвана из шлюза API, который я также создаю в Terraform
  2. Lambda может записывать в журналы Cloudwatch

Iесть следующее, что позволяет шлюзу 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 ]

2 голосов
/ 08 октября 2019

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

Вам необходимо создать политику, а затем прикрепить ее к своей роли. Приведенная выше ссылка содержит более полный пример, чем на странице роли iam.

0 голосов
/ 08 октября 2019

В предыдущий ответ Я записал некоторую справочную информацию о том, как работают роли 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 Gateway и Lambda, вы должны использовать depends_on, чтобы сообщить 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, как это, существует риск того, что функция будет создана и выполнена до завершения вложения роли, ипри этом начальные исполнения вашей функции cможет не написать свои журналы. Если ваша функция не выполняется сразу после ее создания, то, вероятно, этого не произойдет на практике, но было бы полезно включить depends_on, чтобы быть внимательным, и сообщить будущему специалисту по сопровождению о том, что политика доступа к роли также важно для функциональности лямбда-функции.

0 голосов
/ 08 октября 2019
  • Политика 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:*"]
  }

}
  • Полный код terraform можно найти на моем github
...