Skip to content

Instantly share code, notes, and snippets.

@shicholas
Created June 24, 2019 08:41
Show Gist options
  • Save shicholas/00f138eebd5ee7a02a9733d9933f0bf2 to your computer and use it in GitHub Desktop.
Save shicholas/00f138eebd5ee7a02a9733d9933f0bf2 to your computer and use it in GitHub Desktop.
CloudFormation for Cognito & AppSync
---
AWSTemplateFormatVersion: '2010-09-09'
Description: >
This template creates an Authenticated AppSync API & Resolver Lambda
Parameters:
pGraphqlDefinition:
Description: GraphQL Schema
Type: String
pFunctionName:
Description: Name to Call the Function and Role
Type: String
pCodeBucket:
Description: Name of the S3 Bucket
Type: String
pHandler:
Description: Entrypoint in the app where the code will run
Type: String
pCognitoUserPool:
Description: Cognito User Pool Arn
Type: String
pDatabaseUrl:
Description: Cognito Database Url
Type: String
pCognitoUserAppId:
Description: App Id of the Cognito Pool
Type: String
pCognitoUserPoolId:
Description: Id of the Cognito Pool
Type: String
pEnvironment:
Description: Environment the lambdas are in
Type: String
Resources:
GraphqlApi:
Type: AWS::AppSync::GraphQLApi
Properties:
Name: !Ref pFunctionName
AuthenticationType: AMAZON_COGNITO_USER_POOLS
UserPoolConfig:
AppIdClientRegex: !Ref pCognitoUserAppId
UserPoolId: !Ref pCognitoUserPoolId
AwsRegion: us-east-1
DefaultAction: ALLOW
ApiSchema:
Type: "AWS::AppSync::GraphQLSchema"
Properties:
Definition: !Ref pGraphqlDefinition
ApiId: !GetAtt GraphqlApi.ApiId
LambdaDataSource:
Type: "AWS::AppSync::DataSource"
Properties:
ApiId: !GetAtt GraphqlApi.ApiId
Name: lambda
Description: "The Authenticated Api Lambda Role"
Type: "AWS_LAMBDA"
ServiceRoleArn: !GetAtt LambdaExecutionRole.Arn
LambdaConfig:
LambdaFunctionArn: !GetAtt LambdaFunction.Arn
LambdaPermission:
Type: "AWS::Lambda::Permission"
Description: "Allows Cognito to invoke the Cognito Lambda Function"
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref LambdaFunction
Principal: cognito-idp.amazonaws.com
SourceArn: !Ref pCognitoUserPool
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
- appsync.amazonaws.com
Action: sts:AssumeRole
Path: "/"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
Policies:
- PolicyName: !Sub ${pFunctionName}-lambda-policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- lambda:InvokeFunction
- ses:SendEmail
Resource: '*'
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref pCodeBucket
S3Key: !Join
- ''
- - !Ref pEnvironment
- '/code.zip'
FunctionName: !Ref pFunctionName
Handler: !Ref pHandler
Environment:
Variables:
DATABASE_URL: !Ref pDatabaseUrl
API_ENV: !Ref pEnvironment
MemorySize: 1024
Role: !GetAtt LambdaExecutionRole.Arn
Runtime: nodejs8.10
Timeout: 30
LambdaErrors:
Type: 'AWS::CloudWatch::Alarm'
Properties:
AlarmDescription: !Ref pFunctionName
Namespace: 'AWS/Lambda'
MetricName: Errors
Dimensions:
- Name: FunctionName
Value: !Ref LambdaFunction
Statistic: Sum
Period: 300
EvaluationPeriods: 1
Threshold: 0
TreatMissingData: notBreaching
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- 'Fn::ImportValue': !Sub 'marbot-TopicArn'
OKActions:
- 'Fn::ImportValue': !Sub 'marbot-TopicArn'
AlarmCountUserFunctionThrottles:
Type: 'AWS::CloudWatch::Alarm'
Properties:
AlarmDescription: !Sub '${pFunctionName}-Throttling'
Namespace: 'AWS/Lambda'
MetricName: Throttles
Dimensions:
- Name: FunctionName
Value: !Ref LambdaFunction
Statistic: Sum
Period: 300
EvaluationPeriods: 1
Threshold: 0
TreatMissingData: notBreaching
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- 'Fn::ImportValue': !Sub 'marbot-TopicArn'
OKActions:
- 'Fn::ImportValue': !Sub 'marbot-TopicArn'
Outputs:
AppSyncApiId:
Description: ID of the Graphql API
Value: !GetAtt GraphqlApi.ApiId
Export:
Name: !Sub '${AWS::StackName}-ApiId'
LambdaFunctionConsoleUrl:
Description: Console URL for the Lambda Function.
Value: !Join
- ''
- - https://
- !Ref AWS::Region
- ".console.aws.amazon.com/lambda/home?region="
- !Ref AWS::Region
- "#/functions/"
- !Ref LambdaFunction
Export:
Name: !Sub '${AWS::StackName}-LambdaConsoleUrl'
---
AWSTemplateFormatVersion: "2010-09-09"
Description: >
This template creates a Cognito User & Identity Pool
Parameters:
pCodeBucket:
Description: Location of Code Bucket
Type: String
pEnvironment:
Description: Environment of what the Cognito pool is for
Type: String
pDasherizedName:
Description: Prefix of the lambda function
Type: String
pHandler:
Description: Entrypoint of the Lambda function
Type: String
pDatabaseUrl:
Description: Cognito Database Url
Type: String
pUploadBucket:
Description: Bucket where users can upload to their folder
Type: String
Resources:
LambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
Path: "/"
Policies:
- PolicyName: !Ref pDasherizedName
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- cognito-idp:*
Resource: "*"
Lambda:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref pCodeBucket
S3Key: !Join
- ""
- - !Ref pEnvironment
- "/code.zip"
FunctionName: !Ref pDasherizedName
Environment:
Variables:
DATABASE_URL: !Ref pDatabaseUrl
Handler: !Ref pHandler
MemorySize: 1024
Role: !GetAtt LambdaRole.Arn
Runtime: nodejs8.10
Timeout: 30
LambdaErrors:
Type: "AWS::CloudWatch::Alarm"
Properties:
AlarmDescription: !Ref pDasherizedName
Namespace: "AWS/Lambda"
MetricName: Errors
Dimensions:
- Name: FunctionName
Value: !Ref Lambda
Statistic: Sum
Period: 300
EvaluationPeriods: 1
Threshold: 0
TreatMissingData: notBreaching
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- "Fn::ImportValue": !Sub "marbot-TopicArn"
OKActions:
- "Fn::ImportValue": !Sub "marbot-TopicArn"
AlarmCountUserFunctionThrottles:
Type: "AWS::CloudWatch::Alarm"
Properties:
AlarmDescription: !Sub "${pDasherizedName}-Throttling"
Namespace: "AWS/Lambda"
MetricName: Throttles
Dimensions:
- Name: FunctionName
Value: !Ref Lambda
Statistic: Sum
Period: 300
EvaluationPeriods: 1
Threshold: 0
TreatMissingData: notBreaching
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- "Fn::ImportValue": !Sub "marbot-TopicArn"
OKActions:
- "Fn::ImportValue": !Sub "marbot-TopicArn"
SNSRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- "cognito-idp.amazonaws.com"
Action:
- "sts:AssumeRole"
Policies:
- PolicyName: "CognitoSNSPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action: "sns:publish"
Resource: "*"
UserPool:
Type: "AWS::Cognito::UserPool"
Properties:
AdminCreateUserConfig:
InviteMessageTemplate:
EmailSubject: Your temporary password for 1337 Lawyers
EmailMessage: Your username is {username} and temporary password is {####} for 1337 Lawyers
SMSMessage: Your username is {username} and temporary password is {####} for 1337 Lawyers
UnusedAccountValidityDays: 7
AutoVerifiedAttributes:
- email
EmailVerificationSubject: "Your verification code for 1337 Lawyers"
EmailVerificationMessage: "Your verification code is {####}."
SmsAuthenticationMessage: "Your authentication code is {####} for 1337 Lawyers."
SmsVerificationMessage: "Your verification code is {####} for 1337 Lawyers."
MfaConfiguration: "OPTIONAL"
Policies:
PasswordPolicy:
RequireLowercase: false
RequireSymbols: false
RequireNumbers: false
MinimumLength: 16
RequireUppercase: false
UserPoolName: !Ref pEnvironment
LambdaConfig:
CreateAuthChallenge: !GetAtt Lambda.Arn
CustomMessage: !GetAtt Lambda.Arn
DefineAuthChallenge: !GetAtt Lambda.Arn
PostAuthentication: !GetAtt Lambda.Arn
PostConfirmation: !GetAtt Lambda.Arn
PreAuthentication: !GetAtt Lambda.Arn
PreSignUp: !GetAtt Lambda.Arn
VerifyAuthChallengeResponse: !GetAtt Lambda.Arn
SmsConfiguration:
ExternalId: !Sub ${pEnvironment}-texts
SnsCallerArn: !GetAtt SNSRole.Arn
Schema:
- Name: email
StringAttributeConstraints:
MinLength: "0"
MaxLength: "2048"
DeveloperOnlyAttribute: false
Required: true
AttributeDataType: String
Mutable: true
- Name: phone_number
DeveloperOnlyAttribute: false
AttributeDataType: String
Mutable: true
Required: false
LambdaPermission:
Type: AWS::Lambda::Permission
Description: "Allows Cognito to invoke the Cognito Lambda Function"
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref Lambda
Principal: cognito-idp.amazonaws.com
SourceArn: !GetAtt UserPool.Arn
UserPoolClient:
Type: "AWS::Cognito::UserPoolClient"
Properties:
ClientName: !Ref pDasherizedName
GenerateSecret: false
UserPoolId: !Ref UserPool
UploadBucketPolicyRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Federated:
- "cognito-identity.amazonaws.com"
Action:
- "sts:AssumeRoleWithWebIdentity"
Condition:
StringEquals:
"cognito-identity.amazonaws.com:aud": !Ref IdentityPool
"ForAnyValue:StringLike":
"cognito-identity.amazonaws.com:amr": authenticated
Policies:
- PolicyName: "AuthenticatedUsers"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- s3:GetObject
- s3:PutObject
Resource:
- !Join
- ""
- - "arn:aws:s3:::"
- !Ref pUploadBucket
- "/public/*"
- !Join
- ""
- - "arn:aws:s3:::"
- !Ref pUploadBucket
- "/private/${cognito-identity.amazonaws.com:sub}/*"
- !Join
- ""
- - "arn:aws:s3:::"
- !Ref pUploadBucket
- "/protected/${cognito-identity.amazonaws.com:sub}/*"
- Condition:
StringLike:
"s3:prefix":
- "public/"
- "public/*"
- "protected/"
- "protected/*"
- "private/${cognito-identity.amazonaws.com:sub}/"
- "private/${cognito-identity.amazonaws.com:sub}/*"
Effect: "Allow"
Action:
- s3:ListBucket
Resource:
- !Join
- ""
- - "arn:aws:s3:::"
- !Ref pUploadBucket
SupportUserGroup:
Type: AWS::Cognito::UserPoolGroup
Properties:
Description: every employee in the company
GroupName: support
UserPoolId: !Ref UserPool
AdminUserGroup:
Type: AWS::Cognito::UserPoolGroup
Properties:
Description: admins or lawyers of the company
GroupName: admin
UserPoolId: !Ref UserPool
IdentityPool:
Type: AWS::Cognito::IdentityPool
Properties:
AllowUnauthenticatedIdentities: true
CognitoIdentityProviders:
- ClientId: !Ref UserPoolClient
ProviderName: !GetAtt UserPool.ProviderName
UploadBucketPolicyRoleAttachment:
Type: AWS::Cognito::IdentityPoolRoleAttachment
Properties:
IdentityPoolId: !Ref IdentityPool
Roles:
authenticated: !GetAtt UploadBucketPolicyRole.Arn
Outputs:
CognitoUserPoolArn:
Description: The Pool ID of the Cognito User Pool
Value: !GetAtt UserPool.Arn
Export:
Name: !Sub "${AWS::StackName}-CognitoUserPoolArn"
CognitoUserPoolClientId:
Description: The Client ID for AWS AppSync Auth
Value: !Ref UserPool
Export:
Name: !Sub "${AWS::StackName}-CognitoUserPoolId"
CognitoAppId:
Description: The Client ID for AWS AppSync Auth
Value: !Ref UserPoolClient
Export:
Name: !Sub "${AWS::StackName}-CognitoAppId"
CognitoIdentityPoolId:
Description: The Client ID for Identity Pool
Value: !Ref IdentityPool
Export:
Name: !Sub "${AWS::StackName}-IdentityPoolId"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment