AWSTemplateFormatVersion: '2010-09-09' Description: (SO0102-api-stack-competition) - DynamoDB Resources and GraphQL Resolvers for RealTime Live Sports Update Using AWS AppSync. Version %%VERSION%% Metadata: {} Parameters: SolutionId: Type: String Description: solution ID DynamoDBModelTableReadIOPS: Type: Number Description: The number of read IOPS the table should support. Default: 5 DynamoDBModelTableWriteIOPS: Type: Number Description: The number of write IOPS the table should support. Default: 5 DynamoDBBillingMode: Type: String Description: Configure @model types to create DynamoDB tables with PAY_PER_REQUEST or PROVISIONED billing modes. Default: PAY_PER_REQUEST AllowedValues: - PAY_PER_REQUEST - PROVISIONED DynamoDBEnablePointInTimeRecovery: Type: String Description: Whether to enable Point in Time Recovery on the table Default: 'false' AllowedValues: - 'true' - 'false' DynamoDBEnableServerSideEncryption: Type: String Description: Enable server side encryption powered by KMS. Default: 'true' AllowedValues: - 'true' - 'false' AppSyncApiName: Type: String Description: The name of the AppSync API Default: AppSyncSimpleTransform APIKeyExpirationEpoch: Type: Number Description: The epoch time in seconds when the API Key should expire. Setting this to 0 will default to 7 days from the deployment date. Setting this to -1 will not create an API Key. Default: 0 MinValue: -1 CreateAPIKey: Type: Number Description: The boolean value to control if an API Key will be created or not. The value of the property is automatically set by the CLI. If the value is set to 0 no API Key will be created. Default: 0 MinValue: 0 MaxValue: 1 env: Type: String Description: The environment name. e.g. Dev, Test, or Production Default: NONE S3DeploymentBucket: Type: String Description: The S3 bucket containing all deployment assets for the project. S3DeploymentRootKey: Type: String Description: An S3 key relative to the S3DeploymentBucket that points to the root of the deployment directory. AppSyncApiId: Type: String Description: The id of the AppSync API associated with this project. GetAttGraphQLAPIApiId: Type: String Description: Auto-generated parameter that forwards Fn.GetAtt(GraphQLAPI, ApiId) through to nested stacks. Resources: CompetitionTable: Type: AWS::DynamoDB::Table Metadata: cfn_nag: rules_to_suppress: - id: W28 reason: "Table name is constructed with stack name. On update, we need to keep the existing table name." Properties: TableName: !Sub "${SolutionId}-Competition-${env}" KeySchema: - AttributeName: id KeyType: HASH AttributeDefinitions: - AttributeName: id AttributeType: S - AttributeName: sportId AttributeType: S StreamSpecification: StreamViewType: NEW_AND_OLD_IMAGES BillingMode: Fn::If: - ShouldUsePayPerRequestBilling - PAY_PER_REQUEST - Ref: AWS::NoValue ProvisionedThroughput: Fn::If: - ShouldUsePayPerRequestBilling - Ref: AWS::NoValue - ReadCapacityUnits: Ref: DynamoDBModelTableReadIOPS WriteCapacityUnits: Ref: DynamoDBModelTableWriteIOPS GlobalSecondaryIndexes: - IndexName: "gsi-SportCompetitions" KeySchema: - AttributeName: "sportId" KeyType: "HASH" Projection: ProjectionType: "ALL" ProvisionedThroughput: Fn::If: - ShouldUsePayPerRequestBilling - Ref: AWS::NoValue - ReadCapacityUnits: Ref: DynamoDBModelTableReadIOPS WriteCapacityUnits: Ref: DynamoDBModelTableWriteIOPS SSESpecification: SSEEnabled: !If [ShouldUseServerSideEncryption, true, false] PointInTimeRecoverySpecification: Fn::If: - ShouldUsePointInTimeRecovery - PointInTimeRecoveryEnabled: true - Ref: AWS::NoValue DeletionPolicy: Delete CompetitionIAMRole: Type: AWS::IAM::Role Metadata: cfn_nag: rules_to_suppress: - id: W28 reason: "Role name is constructed with graphql API id . On update, we need to keep the existing table name." Properties: RoleName: Fn::If: - HasEnvironmentParameter - Fn::Join: - "-" - - Competition - role - Ref: GetAttGraphQLAPIApiId - Ref: env - Fn::Join: - "-" - - Competition - role - Ref: GetAttGraphQLAPIApiId AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: appsync.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: DynamoDBAccess PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - dynamodb:BatchGetItem - dynamodb:BatchWriteItem - dynamodb:PutItem - dynamodb:DeleteItem - dynamodb:GetItem - dynamodb:Scan - dynamodb:Query - dynamodb:UpdateItem Resource: - !GetAtt CompetitionTable.Arn - !Sub [ "${x0}/*", { x0: !GetAtt CompetitionTable.Arn } ] CompetitionDataSource: Type: AWS::AppSync::DataSource Properties: ApiId: Ref: GetAttGraphQLAPIApiId Name: CompetitionTable Type: AMAZON_DYNAMODB ServiceRoleArn: Fn::GetAtt: - CompetitionIAMRole - Arn DynamoDBConfig: AwsRegion: Ref: AWS::Region TableName: Ref: CompetitionTable DependsOn: - CompetitionIAMRole GetCompetitionResolver: Type: AWS::AppSync::Resolver Properties: ApiId: Ref: GetAttGraphQLAPIApiId DataSourceName: !GetAtt 'CompetitionDataSource.Name' FieldName: getCompetition TypeName: Query RequestMappingTemplateS3Location: Fn::Sub: - s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/${ResolverFileName} - S3DeploymentBucket: Ref: S3DeploymentBucket S3DeploymentRootKey: Ref: S3DeploymentRootKey ResolverFileName: Fn::Join: - "." - - Query - getCompetition - req - vtl ResponseMappingTemplateS3Location: Fn::Sub: - s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/${ResolverFileName} - S3DeploymentBucket: Ref: S3DeploymentBucket S3DeploymentRootKey: Ref: S3DeploymentRootKey ResolverFileName: Fn::Join: - "." - - Query - getCompetition - res - vtl ListCompetitionResolver: Type: AWS::AppSync::Resolver Properties: ApiId: Ref: GetAttGraphQLAPIApiId DataSourceName: !GetAtt 'CompetitionDataSource.Name' FieldName: listCompetitions TypeName: Query RequestMappingTemplateS3Location: Fn::Sub: - s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/${ResolverFileName} - S3DeploymentBucket: Ref: S3DeploymentBucket S3DeploymentRootKey: Ref: S3DeploymentRootKey ResolverFileName: Fn::Join: - "." - - Query - listCompetitions - req - vtl ResponseMappingTemplateS3Location: Fn::Sub: - s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/${ResolverFileName} - S3DeploymentBucket: Ref: S3DeploymentBucket S3DeploymentRootKey: Ref: S3DeploymentRootKey ResolverFileName: Fn::Join: - "." - - Query - listCompetitions - res - vtl CreateCompetitionResolver: Type: AWS::AppSync::Resolver Properties: ApiId: Ref: GetAttGraphQLAPIApiId DataSourceName: !GetAtt 'CompetitionDataSource.Name' FieldName: createCompetition TypeName: Mutation RequestMappingTemplateS3Location: Fn::Sub: - s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/${ResolverFileName} - S3DeploymentBucket: Ref: S3DeploymentBucket S3DeploymentRootKey: Ref: S3DeploymentRootKey ResolverFileName: Fn::Join: - "." - - Mutation - createCompetition - req - vtl ResponseMappingTemplateS3Location: Fn::Sub: - s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/${ResolverFileName} - S3DeploymentBucket: Ref: S3DeploymentBucket S3DeploymentRootKey: Ref: S3DeploymentRootKey ResolverFileName: Fn::Join: - "." - - Mutation - createCompetition - res - vtl UpdateCompetitionResolver: Type: AWS::AppSync::Resolver Properties: ApiId: Ref: GetAttGraphQLAPIApiId DataSourceName: !GetAtt 'CompetitionDataSource.Name' FieldName: updateCompetition TypeName: Mutation RequestMappingTemplateS3Location: Fn::Sub: - s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/${ResolverFileName} - S3DeploymentBucket: Ref: S3DeploymentBucket S3DeploymentRootKey: Ref: S3DeploymentRootKey ResolverFileName: Fn::Join: - "." - - Mutation - updateCompetition - req - vtl ResponseMappingTemplateS3Location: Fn::Sub: - s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/${ResolverFileName} - S3DeploymentBucket: Ref: S3DeploymentBucket S3DeploymentRootKey: Ref: S3DeploymentRootKey ResolverFileName: Fn::Join: - "." - - Mutation - updateCompetition - res - vtl DeleteCompetitionResolver: Type: AWS::AppSync::Resolver Properties: ApiId: Ref: GetAttGraphQLAPIApiId DataSourceName: !GetAtt 'CompetitionDataSource.Name' FieldName: deleteCompetition TypeName: Mutation RequestMappingTemplateS3Location: Fn::Sub: - s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/${ResolverFileName} - S3DeploymentBucket: Ref: S3DeploymentBucket S3DeploymentRootKey: Ref: S3DeploymentRootKey ResolverFileName: Fn::Join: - "." - - Mutation - deleteCompetition - req - vtl ResponseMappingTemplateS3Location: Fn::Sub: - s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/${ResolverFileName} - S3DeploymentBucket: Ref: S3DeploymentBucket S3DeploymentRootKey: Ref: S3DeploymentRootKey ResolverFileName: Fn::Join: - "." - - Mutation - deleteCompetition - res - vtl CompetitionfeedConfigResolver: Type: AWS::AppSync::Resolver Properties: ApiId: Ref: GetAttGraphQLAPIApiId DataSourceName: NONE FieldName: feedConfig TypeName: Competition RequestMappingTemplateS3Location: Fn::Sub: - s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/${ResolverFileName} - S3DeploymentBucket: Ref: S3DeploymentBucket S3DeploymentRootKey: Ref: S3DeploymentRootKey ResolverFileName: Fn::Join: - "." - - Competition - feedConfig - req - vtl ResponseMappingTemplateS3Location: Fn::Sub: - s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/${ResolverFileName} - S3DeploymentBucket: Ref: S3DeploymentBucket S3DeploymentRootKey: Ref: S3DeploymentRootKey ResolverFileName: Fn::Join: - "." - - Competition - feedConfig - res - vtl Outputs: GetAttCompetitionTableStreamArn: Description: DynamoDB table StreamArn. Value: !Ref CompetitionTable Export: Name: Fn::Join: - ":" - - Ref: AppSyncApiId - GetAtt - CompetitionTable - StreamArn GetAttCompetitionDataSourceName: Description: Model DataSource name. Value: !GetAtt 'CompetitionDataSource.Name' Export: Name: Fn::Join: - ":" - - Ref: AppSyncApiId - GetAtt - CompetitionDataSource - Name GetAttCompetitionTableName: Description: DynamoDB table name. Value: Ref: CompetitionTable Export: Name: Fn::Join: - ":" - - Ref: AppSyncApiId - GetAtt - CompetitionTable - Name Mappings: {} Conditions: ShouldUsePayPerRequestBilling: Fn::Equals: - Ref: DynamoDBBillingMode - PAY_PER_REQUEST ShouldUsePointInTimeRecovery: Fn::Equals: - Ref: DynamoDBEnablePointInTimeRecovery - 'true' ShouldUseServerSideEncryption: Fn::Equals: - Ref: DynamoDBEnableServerSideEncryption - 'true' ShouldCreateAPIKey: Fn::Equals: - Ref: CreateAPIKey - 1 APIKeyExpirationEpochIsPositive: Fn::And: - Fn::Not: - Fn::Equals: - Ref: APIKeyExpirationEpoch - -1 - Fn::Not: - Fn::Equals: - Ref: APIKeyExpirationEpoch - 0 HasEnvironmentParameter: Fn::Not: - Fn::Equals: - Ref: env - NONE