--- AWSTemplateFormatVersion: 2010-09-09 Description: AWS EKS Reference Administration Site with CloudFront, Cognito User Pool and Client, OAI and S3 Buckets Parameters: AdminEmailAddress: Description: Email address of admin user to receive temporary password notification AllowedPattern: ^[^\s@]+@[^\s@]+\.[^\s@]+$ ConstraintDescription: Must be a valid email address. Type: String CloudFrontAppCertArn: Type: String CustomDomainName: Type: String S3OAIUserId: Type: String S3OAIId: Type: String HostedZoneId: Type: String Resources: AdminAppBucket: Type: AWS::S3::Bucket DeletionPolicy : Retain AdminAppSiteReadPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref AdminAppBucket PolicyDocument: Statement: - Action: 's3:GetObject' Effect: Allow Resource: !Sub 'arn:aws:s3:::${AdminAppBucket}/*' Principal: CanonicalUser: !Ref S3OAIUserId AdminAppSite: Type: AWS::CloudFront::Distribution Properties: DistributionConfig: Aliases: - !Sub 'admin.${CustomDomainName}' CustomErrorResponses: # Needed to support angular routing - ErrorCode: 403 ResponseCode: 200 ResponsePagePath: '/index.html' - ErrorCode: 404 ResponseCode: 200 ResponsePagePath: '/index.html' DefaultCacheBehavior: AllowedMethods: - GET - HEAD - OPTIONS CachedMethods: - GET - HEAD - OPTIONS Compress: true DefaultTTL: 3600 # in seconds ForwardedValues: Cookies: Forward: none QueryString: false MaxTTL: 86400 # in seconds MinTTL: 60 # in seconds TargetOriginId: s3origin ViewerProtocolPolicy: 'allow-all' DefaultRootObject: 'index.html' Enabled: true HttpVersion: http2 Origins: - DomainName: !GetAtt AdminAppBucket.RegionalDomainName Id: s3origin S3OriginConfig: OriginAccessIdentity: !Sub origin-access-identity/cloudfront/${S3OAIId} PriceClass: 'PriceClass_All' ViewerCertificate: AcmCertificateArn: !Ref CloudFrontAppCertArn MinimumProtocolVersion: 'TLSv1.2_2018' SslSupportMethod: 'sni-only' AdminAppSiteAlias: Type: AWS::Route53::RecordSet Properties: AliasTarget: DNSName: !GetAtt AdminAppSite.DomainName EvaluateTargetHealth: false HostedZoneId: 'Z2FDTNDATAQYW2' # This is hardcoded per the docs. Who knew? HostedZoneId : !Ref HostedZoneId Name: !Sub admin.${CustomDomainName} Type: A UserPool: Type: AWS::Cognito::UserPool DependsOn: AdminAppSite Properties: AdminCreateUserConfig: AllowAdminCreateUserOnly: true InviteMessageTemplate: EmailMessage: !Sub | Welcome to SaaS Admin App for EKS!

You can log into the app here.
Your username is: {username}
Your temporary password is: {####}
EmailSubject: SaaS Admin temporary password for environment EKS SaaS Solution UserPoolName: Fn::Sub: ${AWS::StackName}-UserPool Policies: PasswordPolicy: MinimumLength: 8 RequireLowercase: true RequireNumbers: true RequireSymbols: false RequireUppercase: true TemporaryPasswordValidityDays: 7 UsernameAttributes: - email Schema: - AttributeDataType: String Name: email Required: true Mutable: true UserPoolClient: Type: AWS::Cognito::UserPoolClient Properties: AllowedOAuthFlowsUserPoolClient: true AllowedOAuthFlows: - code - implicit AllowedOAuthScopes: - phone - email - openid - profile CallbackURLs: - !Sub https://admin.${CustomDomainName} ClientName: !Sub EksAdminAppClient-${AWS::Region} DefaultRedirectURI: !Sub https://admin.${CustomDomainName} GenerateSecret: false UserPoolId: !Ref UserPool ExplicitAuthFlows: - ALLOW_ADMIN_USER_PASSWORD_AUTH - ALLOW_CUSTOM_AUTH - ALLOW_USER_SRP_AUTH - ALLOW_REFRESH_TOKEN_AUTH LogoutURLs: - !Sub https://admin.${CustomDomainName}/signout PreventUserExistenceErrors: ENABLED RefreshTokenValidity: 30 SupportedIdentityProviders: - COGNITO CustomUserPoolDomain: Type: AWS::Cognito::UserPoolDomain Properties: Domain: !Ref AdminAppBucket UserPoolId: Ref: UserPool AdminAppAdminUser: Type: AWS::Cognito::UserPoolUser Properties: DesiredDeliveryMediums: - EMAIL ForceAliasCreation: false UserAttributes: - Name: "email" Value: !Ref AdminEmailAddress - Name: "email_verified" Value: "true" Username: !Ref AdminEmailAddress UserPoolId: !Ref UserPool Outputs: TenantManagementUrl: Description: The URL of the admin site Value: !Sub https://${AdminAppSite.DomainName} AdminBucket: Description: The name of the bucket for uploading the Tenant Management site to Value: !Ref AdminAppBucket AdminOAuthClientId: Description: The OAuth AppClientID to configure the Admin Client with Value: !Ref UserPoolClient AdminOAuthProviderUrl: Description: The URL of the authorization server for the admin client Value: !GetAtt UserPool.ProviderURL AdminOAuthCustomDomain: Description: The custom cognito domain for this app client Value: !Ref CustomUserPoolDomain