Создание функции Lambda@edge с использованием Terraform и Serverless Framework - PullRequest
0 голосов
/ 21 апреля 2020

Я пытаюсь создать функцию Lambda@edge с Terraform (роли iam) и безсерверной средой, конвейер завершен, но CloudFront не может подключиться к Lambda с этим сообщением об ошибке

The Lambda function associated with the CloudFront distribution is invalid or doesn't have the required permissions. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.

I Я не слишком знаком с настройкой Lambda@edge (и Terraform), с консоли AWS я вижу arn лямбды, сохраненной в разделе поведения CloudFront, но не вижу ни одного триггера в лямбде.

Это настройка Terraform

resource "aws_iam_policy" "sls-user-policy" {
  name = "${var.service_name}-sls-user-policy-${terraform.workspace}"

  policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:Describe*",
                "cloudformation:List*",
                "cloudformation:Get*",
                "cloudformation:CreateStack",
                "cloudformation:UpdateStack",
                "cloudformation:DeleteStack"
            ],
            "Resource": "arn:aws:cloudformation:${var.region}:${var.aws_account_number}:stack/${var.service_name}*/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:ValidateTemplate",
                "cloudfront:ListDistributionsByLambdaFunction",
                "iam:PassRole"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:GetRole",
                "iam:PassRole",
                "iam:CreateRole",
                "iam:CreateServiceLinkedRole",
                "iam:DeleteRole",
                "iam:DetachRolePolicy",
                "iam:PutRolePolicy",
                "iam:AttachRolePolicy",
                "iam:DeleteRolePolicy"
            ],
            "Resource": [
                "arn:aws:iam::${var.aws_account_number}:role/${var.service_name}-${terraform.workspace}-*",
                "arn:aws:iam::${var.aws_account_number}:role/${var.service_name}*-lambdaRole",
                "arn:aws:iam::${var.aws_account_number}:role/aws-service-role/ops.apigateway.amazonaws.com/AWSServiceRoleForAPIGateway",
                "arn:aws:iam::${var.aws_account_number}:role/aws-service-role/replicator.lambda.amazonaws.com/AWSServiceRoleForLambdaReplicator",
                "arn:aws:iam::${var.aws_account_number}:role/aws-service-role/logger.cloudfront.amazonaws.com/AWSServiceRoleForCloudFrontLogger"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "events:Put*",
                "events:Remove*",
                "events:Delete*",
                "events:Describe*"
            ],
            "Resource": "arn:aws:events::${var.aws_account_number}:rule/${var.service_name}*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:DescribeLogGroups"
            ],
            "Resource": "arn:aws:logs:${var.region}:${var.aws_account_number}:log-group::log-stream:*"
        },
        {
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:DeleteLogGroup",
                "logs:DeleteLogStream",
                "logs:DescribeLogStreams",
                "logs:FilterLogEvents",
                "logs:PutLogsEvent"
            ],
            "Resource": [
                "arn:aws:logs:${var.region}:${var.aws_account_number}:log-group:/aws/*/${var.service_name}*:log-stream:*",
                "arn:aws:logs:${var.region}:${var.aws_account_number}:/aws/cloudfront/*"
            ],
            "Effect": "Allow"
        },
        {
            "Effect": "Allow",
            "Action": [
                "lambda:GetFunction",
                "lambda:CreateFunction",
                "lambda:DeleteFunction",
                "lambda:UpdateFunctionConfiguration",
                "lambda:UpdateFunctionCode",
                "lambda:ListVersionsByFunction",
                "lambda:PublishVersion",
                "lambda:CreateAlias",
                "lambda:DeleteAlias",
                "lambda:UpdateAlias",
                "lambda:GetFunctionConfiguration",
                "lambda:AddPermission",
                "lambda:RemovePermission",
                "lambda:InvokeFunction",
                "lambda:ListTags",
                "lambda:TagResource",
                "lambda:UntagResource",
                "lambda:EnableReplication*",
                "lambda:DisableReplication"
            ],
            "Resource": [
                "arn:aws:lambda:*:${var.aws_account_number}:function:${var.service_name}*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "apigateway:GET",
                "apigateway:POST",
                "apigateway:PUT",
                "apigateway:PATCH",
                "apigateway:DELETE",
                "apigateway:UpdateRestApiPolicy"
            ],
            "Resource": [
                "arn:aws:apigateway:${var.region}::/restapis",
                "arn:aws:apigateway:${var.region}::/restapis/*",
                "arn:aws:apigateway:${var.region}::/apikeys",
                "arn:aws:apigateway:${var.region}::/apikeys/*",
                "arn:aws:apigateway:${var.region}::/usageplans",
                "arn:aws:apigateway:${var.region}::/usageplans/*",
                "arn:aws:apigateway:${var.region}::/tags",
                "arn:aws:apigateway:${var.region}::/tags/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudfront:CreateDistribution",
                "cloudfront:GetDistribution",
                "cloudfront:ListDistributions",
                "cloudfront:TagResource",
                "cloudfront:UntagResource",
                "cloudfront:UpdateDistribution"
            ],
            "Resource": "arn:aws:cloudfront::${var.aws_account_number}:distribution/*"
        },
        {
            "Effect": "Allow",
            "Action": [
              "states:ListStateMachines",
              "states:ListActivities",
              "states:CreateStateMachine",
              "states:UpdateStateMachine",
              "states:DeleteStateMachine",
              "states:CreateActivity",
              "states:TagResource",
              "states:StartExecution"
            ],
            "Resource": [
              "arn:aws:states:*:${var.aws_account_number}:stateMachine:*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "sns:Subscribe",
                "sns:Unsubscribe"
            ],
            "Resource": "arn:aws:sns:${var.region}:${var.aws_account_number}:${var.service_name}-*-${terraform.workspace}"
        }
    ]
}
EOF
}

Serverless.yml

service: service-integration

frameworkVersion: '>=1.1.0 <2.0.0'

plugins:
  - serverless-webpack
  - serverless-offline
  - serverless-iam-roles-per-function

custom:
  defaultStage: dev
  stage: ${opt:stage, self:custom.defaultStage}
  defaultBuild: 0
  webpack:
    webpackConfig: ./webpack/${self:custom.stage}.config.js
    forceExclude:
      - aws-sdk
  serverless-iam-roles-per-function:
    defaultInherit: true
  apigwBinary:
    types:
      - 'application/octet-stream'

provider:
  name: aws
  stage: ${self:custom.stage}
  runtime: nodejs10.x
  region: us-east-1

functions:
  edgeFunction:
    handler: src/services/edge-function/edge-function.run
    memorySize: 2048
    timeout: 30
    events:
      - cloudFront:
          eventType: origin-request
          pathPattern: /api/edge-function/*/*
          isDefaultOrigin: true
          origin: https://custom-origin.com
          behavior:
            ViewerProtocolPolicy: https-only
            AllowedMethods:
              - 'GET'
              - 'HEAD'
              - 'OPTIONS'
              - 'PUT'
              - 'PATCH'
              - 'POST'
              - 'DELETE'

resources:
  Resources:
    CloudFrontDistribution:
      Type: AWS::CloudFront::Distribution
      Properties:
        DistributionConfig:
          PriceClass: PriceClass_200

    # got the below section from this link
    # https://www.pveller.com/lambda-edge-serverless/
    IamRoleLambdaExecution:
      Type: AWS::IAM::Role
      Properties:
        AssumeRolePolicyDocument:
          Statement:
            - Effect: Allow
              Principal:
                Service:
                  - lambda.amazonaws.com
                  - edgelambda.amazonaws.com

package:
  individually: true
...