Добавить разрешение для запуска лямбда-шлюза в API-интерфейсе через облачную информацию - PullRequest
0 голосов
/ 30 апреля 2018

Я пытаюсь создать шлюз API, указывающий на лямбду через прокси, используя cloudformation:

Сначала я создаю свой рут и даю ему разрешение:

  RestApiHamed:
   Type: 'AWS::ApiGateway::RestApi'
   Properties:
   Name: hamed-proxy-test
  APIGatewayToLambdaPermission:
   Type: AWS::Lambda::Permission
   DependsOn: RestApiHamed
   Properties:
     Action: lambda:invokeFunction
     FunctionName: test-stg1-lambda-product-get
     Principal: apigateway.amazonaws.com
     SourceArn: #!Sub "arn:aws:execute- 
      api:${AWS::Region}:${AWS::AccountId}:RestApiHamed/*"
      Fn::Join:
      - ''
      - - 'arn:aws:execute-api:'
        - Ref: AWS::Region
        - ":"
        - Ref: AWS::AccountId
        - ":"
        - Ref: RestApiHamed
        - "/*"

Затем я создаю свой метод:

  ChannelsStoriesGetMethod:
   Type: AWS::ApiGateway::Method
   DependsOn: APIGatewayToLambdaPermission
   Properties:
     AuthorizationType: NONE
     HttpMethod: GET
     Integration:
       Type: HTTP
       IntegrationHttpMethod: GET
       IntegrationResponses:
        -
          StatusCode: 200
       Type: AWS_PROXY
       Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:048947288163:function:zuora-stg1-lambda-product-get/invocations
    ResourceId: !Ref ChannelsStoriesPath
    RestApiId:
      Ref: RestApiHamed
    MethodResponses:
    - StatusCode: 200
      ResponseParameters:
        method.response.header.Access-Control-Allow-Origin: true

Теперь, когда я запускаю облачную информацию, она оказывается успешной, и я вижу свои ворота, но когда я пробую шлюз, я получаю:

 <Message>Unable to determine service/operation name to be 
  authorized</Message>
</AccessDeniedException>
 Execution failed due to configuration error: Malformed Lambda proxy response

Но как только я перехожу к запросу на интеграцию и нажимаю clcik для редактирования в лямбда-функции, а затем нажимаю кнопку «Сохранить», я получаю всплывающее окно с запросом на вложение разрешений, и когда я принимаю это, оно начинает работать. В чем проблема? Я добавляю разрешение в мой код cfn и ожидаю, что этот кусок, как вы видите, выполняет свою работу. Должен ли я добавить что-нибудь еще?

Полный код CFN выглядит следующим образом:

{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "API gateway for TJ services",
"Parameters": {
    "BusinessUnit": {
        "Description": "BusinessUnit",
        "Type": "String",
        "ConstraintDescription": "Any string"
    },
    "project": {
        "Description": "project",
        "Type": "String",
        "ConstraintDescription": "Any string"
    },
    "EnvironmentApp": {
        "Description": "EnvironmentApp",
        "Type": "String",
        "ConstraintDescription": "Any string"
    },
    "EnvironmentInfra": {
        "Description": "EnvironmentInfra",
        "Type": "String",
        "ConstraintDescription": "Any string"
    }
},
"Resources": {
    "LambdaHelloworldRole": {
        "Type": "AWS::IAM::Role",
        "Properties": {
            "RoleName": "${project}-${EnvironmentApp}-lambda-helloworld",
            "AssumeRolePolicyDocument": {
                "Version": "2012-10-17",
                "Statement": [{
                    "Effect": "Allow",
                    "Principal": {
                        "Service": [
                            "lambda.amazonaws.com",
                            "apigateway.amazonaws.com"
                        ]
                    },
                    "Action": [
                        "sts:AssumeRole"
                    ]
                }]
            },
            "Path": "/",
            "Policies": [{
                "PolicyName": "${project}-${EnvironmentApp}-lambda-helloworld",
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [{
                        "Effect": "Allow",
                        "Action": [
                            "logs:CreateLogGroup",
                            "logs:CreateLogStream",
                            "logs:PutLogEvents",
                            "logs:DescribeLogGroups",
                            "logs:DescribeLogStreams",
                            "logs:PutLogEvents",
                            "logs:GetLogEvents",
                            "logs:FilterLogEvents"
                        ],
                        "Resource": "*"
                    }]
                }
            }]
        }
    },
    "LambdaHelloworld": {
        "Type": "AWS::Lambda::Function",
        "Properties": {
            "Handler": "index.lambda_handler",
            "Timeout": 180,
            "MemorySize": 1536,
            "Environment": {
                "Variables": {
                    "test": "test"
                }
            },
            "FunctionName": "${project}-${EnvironmentApp}-lambda-helloworld-pipeline-test",
            "Role": {
                "Fn::GetAtt": [
                    "LambdaHelloworldRole",
                    "Arn"
                ]
            },
            "Code": {
                "ZipFile": {
                    "Fn::Join": [
                        "\n", [
                            "import boto3",
                            "import http.client",
                            "import json",
                            "import urllib.request",
                            "import urllib.parse",
                            "import sys",
                            "def lambda_handler(event, context):",
                            "   return { 'statusCode': 200, 'headers': { 'Access-Control-Allow-Origin': '*' }, 'body': 'hello world stg2'}"
                        ]
                    ]
                }
            },
            "Runtime": "python3.6"
        }
    },
    "RestApiHellowworld": {
        "Type": "AWS::ApiGateway::RestApi",
        "Properties": {
            "Name": "hamed-proxy-test"
        }
    },
    "APIGatewayToLambdaPermission": {
        "Type": "AWS::Lambda::Permission",
        "DependsOn": "RestApiHellowworld",
        "Properties": {
            "Action": "lambda:invokeFunction",
            "FunctionName": "zuora-stg1-lambda-product-get",
            "Principal": "apigateway.amazonaws.com"
        }
    },
    "ChannelsStoriesPath": {
        "Type": "AWS::ApiGateway::Resource",
        "Properties": {
            "RestApiId": {
                "Ref": "RestApiHellowworld"
            },
            "ParentId": {
                "Fn::GetAtt": [
                    "RestApiHellowworld",
                    "RootResourceId"
                ]
            },
            "PathPart": "stories"
        }
    },
    "ChannelsStoriesOptionsMethod": {
        "Type": "AWS::ApiGateway::Method",
        "Properties": {
            "AuthorizationType": "NONE",
            "RestApiId": {
                "Ref": "RestApiHellowworld"
            },
            "ResourceId": "ChannelsStoriesPath",
            "HttpMethod": "OPTIONS",
            "Integration": {
                "IntegrationResponses": [{
                    "StatusCode": 200,
                    "ResponseParameters": {
                        "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
                        "method.response.header.Access-Control-Allow-Methods": "'POST,OPTIONS,GET,PUT'",
                        "method.response.header.Access-Control-Allow-Origin": "'*'"
                    },
                    "ResponseTemplates": {
                        "application/json": ""
                    }
                }],
                "PassthroughBehavior": "WHEN_NO_MATCH",
                "RequestTemplates": {
                    "application/json": "{\"statusCode\": 200}"
                },
                "Type": "MOCK"
            },
            "MethodResponses": [{
                "StatusCode": 200,
                "ResponseModels": {
                    "application/json": "Empty"
                },
                "ResponseParameters": {
                    "method.response.header.Access-Control-Allow-Headers": true,
                    "method.response.header.Access-Control-Allow-Methods": true,
                    "method.response.header.Access-Control-Allow-Origin": true
                }
            }]
        }
    },
    "ChannelsStoriesGetMethod": {
        "Type": "AWS::ApiGateway::Method",
        "DependsOn": [
            "APIGatewayToLambdaPermission",
            "LambdaHelloworld"
        ],
        "Properties": {
            "AuthorizationType": "NONE",
            "HttpMethod": "GET",
            "Integration": {
                "Type": "AWS_PROXY",
                "IntegrationHttpMethod": "GET",
                "IntegrationResponses": [{
                    "StatusCode": 200,
                    "ResponseParameters": {
                        "method.response.header.Access-Control-Allow-Origin": "'*'"
                    }
                }],
                "Uri": {
                    "Fn::Join": [
                        "", [
                            "arn:aws:apigateway:",
                            {
                                "Ref": "AWS::Region"
                            },
                            ":",
                            "lambda:path/2015-03-31/functions/",
                            "arn:aws:lambda:us-east-1:048947288163:function:${project}-",
                            "${stageVariables.stg}-lambda-helloworld-pipeline-test",
                            "/invocations"
                        ]
                    ]
                }
            },
            "ResourceId": "ChannelsStoriesPath",
            "RestApiId": {
                "Ref": "RestApiHellowworld"
            },
            "MethodResponses": [{
                "StatusCode": 200
            }]
        }
    },
    "ApiGatewayEventLogGroup": {
        "Type": "AWS::Logs::LogGroup",
        "Properties": {
            "LogGroupName": {
                "Fn::Join": [
                    "", [
                        "/aws/apigateway/",
                        "${project}-${EnvironmentApp}-helloworld"
                    ]
                ]
            },
            "RetentionInDays": 1
        }
    },
    "ApiGatewayEventLogStream": {
        "Type": "AWS::Logs::LogStream",
        "Properties": {
            "LogGroupName": {
                "Ref": "ApiGatewayEventLogGroup"
            },
            "LogStreamName": "${project}-${EnvironmentApp}-helloworld"
        },
        "DependsOn": [
            "ApiGatewayEventLogGroup"
        ]
    },
    "ApiGatewayCloudWatchLogsRole": {
        "Type": "AWS::IAM::Role",
        "Properties": {
            "AssumeRolePolicyDocument": {
                "Version": "2012-10-17",
                "Statement": [{
                    "Effect": "Allow",
                    "Principal": {
                        "Service": [
                            "apigateway.amazonaws.com"
                        ]
                    },
                    "Action": [
                        "sts:AssumeRole"
                    ]
                }]
            },
            "Policies": [{
                "PolicyName": "ApiGatewayLogsPolicy",
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [{
                        "Effect": "Allow",
                        "Action": [
                            "logs:*"
                        ],
                        "Resource": [
                            [
                                "ApiGatewayEventLogGroup",
                                "Arn"
                            ],
                            "*"
                        ]
                    }]
                }
            }]
        }
    },
    "ApiGatewayAccount": {
        "Type": "AWS::ApiGateway::Account",
        "DependsOn": "ApiGatewayCloudWatchLogsRole",
        "Properties": {
            "CloudWatchRoleArn": {
                "Fn::GetAtt": [
                    "ApiGatewayCloudWatchLogsRole",
                    "Arn"
                ]
            }
        }
    },
    "ApiDeployment": {
        "Type": "AWS::ApiGateway::Deployment",
        "DependsOn": "ChannelsStoriesGetMethod",
        "Properties": {
            "RestApiId": {
                "Ref": "RestApiHellowworld"
            }
        }
    },
    "ApiStage": {
        "DependsOn": [
            "ApiGatewayAccount"
        ],
        "Type": "AWS::ApiGateway::Stage",
        "Properties": {
            "DeploymentId": {
                "Ref": "ApiDeployment"
            },
            "MethodSettings": [{
                "DataTraceEnabled": true,
                "HttpMethod": "*",
                "LoggingLevel": "INFO",
                "ResourcePath": "/*"
            }],
            "RestApiId": {
                "Ref": "RestApiHellowworld"
            },
            "StageName": "${EnvironmentApp}",
            "Variables": {
                "stg": "${EnvironmentApp}"
            }
        }
    }
},
"Outputs": {
    "RootResourceId": {
        "Description": "Tj Services Rest API root resource id",
        "Value": "RestApiHellowworld.RootResourceId",
        "Export": {
            "Name": "${project}-${EnvironmentApp}-RootResourceId-helloworld"
        }
    },
    "RestTjApi": {
        "Description": "Tj Services Rest API",
        "Value": "RestApiHellowworld",
        "Export": {
            "Name": "${project}-restApi-tj-services-helloworld"
        }
    }
}

}

1 Ответ

0 голосов
/ 01 мая 2018

Я не думаю, что ваш скрипт облачной информации может добавить разрешение на запуск лямбда-функции для API-шлюза. Я бы предпочел добиться этого следующим образом

APIName:
 Type: "AWS::ApiGateway::RestApi"
 Properties:
  Description: "Description"
  Name: "APIName"
  FailOnWarnings: true

APILambdaPermission:
 Type: "AWS::Lambda::Permission"
 Properties:
  Action: "lambda:InvokeFunction"
  FunctionName: !Ref LambdaFunctionName
  Principal: "apigateway.amazonaws.com"


LambdaFunctionName:
 Type: "AWS::Serverless::Function"
 Properties:
  Handler: index.handler
  Runtime: nodejs6.10
  CodeUri: s3://codeBucketName/index.zip
  Role: !GetAtt RoleName.Arn

RoleName:
 Type: AWS::IAM::Role
 Properties:
  AssumeRolePolicyDocument:
    Version: 2012-10-17
    Statement:
      - Effect: Allow
        Principal:
          Service: lambda.amazonaws.com
        Action: sts:AssumeRole
  ManagedPolicyArns:
    - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
...