Recently I've been working on stand alone cloud formation template, which will create REST API, via API gateway and lambda hooked behind doing all the business logic.
Right now it is public, anyone can make the call to APIGW url and get the response. I want to make it secure so that only certain people with a IAM role will be able to call the APIGW.
If there is any other better way securing the same, any suggestion are appreciated.
Current cloudformation
AWSTemplateFormatVersion: 2010-09-09
Description: My API Gateway and Lambda function
Parameters:
apiGatewayName:
Type: String
Default: final-apigw-2
apiGatewayStageName:
Type: String
Default: v1
apiGatewayHTTPMethod:
Type: String
Default: ANY
lambdaFunctionName:
Type: String
AllowedPattern: "[a-zA-Z0-9]+[a-zA-Z0-9-]+[a-zA-Z0-9]+"
Default: final-lambda-2
Resources:
apiGateway:
Type: AWS::ApiGateway::RestApi
Properties:
Description: Example API Gateway
EndpointConfiguration:
Types:
- REGIONAL
Name: !Ref apiGatewayName
apiGatewayLambdaResource:
Type: 'AWS::ApiGateway::Resource'
Properties:
RestApiId: !Ref apiGateway
PathPart: '{proxy+}'
ParentId: !GetAtt apiGateway.RootResourceId
apiGatewayLambdaResourceMethod:
Type: 'AWS::ApiGateway::Method'
Properties:
AuthorizationType: NONE
RestApiId: !Ref apiGateway
ResourceId: !Ref apiGatewayLambdaResource
HttpMethod: ANY
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST
Uri: !Sub
- >-
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations
- lambdaArn: !GetAtt lambdaFunction.Arn
IntegrationResponses:
- ResponseTemplates:
application/json: ""
StatusCode: 200
PassthroughBehavior: WHEN_NO_TEMPLATES
apiGatewayDeployment:
Type: AWS::ApiGateway::Deployment
DependsOn:
- apiGatewayLambdaResourceMethod
Properties:
RestApiId: !Ref apiGateway
StageName: !Ref apiGatewayStageName
lambdaFunction:
Type: AWS::Lambda::Function
Properties:
Code:
ZipFile: |
exports.handler = async (event) => {
// TODO implement
const response = {
statusCode: 200,
body: JSON.stringify(event),
};
return response;
};
Description: Example Lambda function
FunctionName: !Ref lambdaFunctionName
Handler: index.handler
Role: !GetAtt lambdaIAMRole.Arn
Runtime: nodejs12.x
lambdaApiGatewayInvoke:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt lambdaFunction.Arn
Principal: apigateway.amazonaws.com
# note: if route *not* at API Gateway root, `SourceArn` would take the form of:
# arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/${apiGatewayStageName}/${apiGatewayHTTPMethod}/PATH_PART
SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/${apiGatewayStageName}/${apiGatewayHTTPMethod}/*
lambdaIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Policies:
- PolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Effect: Allow
Resource:
- !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${lambdaFunctionName}:*
PolicyName: lambda
lambdaLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub /aws/lambda/${lambdaFunctionName}
RetentionInDays: 90
Outputs:
apiGatewayInvokeURL:
Value: !Sub https://${apiGateway}.execute-api.${AWS::Region}.amazonaws.com/${apiGatewayStageName}
lambdaArn:
Value: !GetAtt lambdaFunction.Arn
UPDATE
Found this doc : https://docs.aws.amazon.com/apigateway/api-reference/resource/method/
authorizationType
The method's authorization type. Valid values are NONE for open access, AWS_IAM for using AWS IAM permissions, CUSTOM for using a custom authoriser, or COGNITO_USER_POOLS for using a Cognito user pool.
I added the authorisation type as AWS_IAM, but still I'm able to call the APIGW endpoint, I am missing anything