Description: > MediaSearch Solution - Finder stack (v0.3.2) Resources: ##Create Cognito Userpool for Authentication UserPool: Type: 'AWS::Cognito::UserPool' Properties: AliasAttributes: - email AutoVerifiedAttributes: - email UsernameConfiguration: CaseSensitive: false AdminCreateUserConfig: AllowAdminCreateUserOnly: true InviteMessageTemplate: EmailMessage: "

Hello {username},\n

Welcome to Finder App! Your temporary password is:\n

{####}
\n

When the CloudFormation stack is COMPLETE, use the MediaSearchFinderURL in the Outputs tab of the CloudFormation stack to login using {username} as username, set your permanent password, and start searching!\n

Good luck!\n" EmailSubject: "Welcome to Finder Web App" Admins: Type: 'AWS::Cognito::UserPoolGroup' Condition: EnableAuth Properties: GroupName: 'Admins' UserPoolId: !Ref UserPool AdminUser: Type: 'AWS::Cognito::UserPoolUser' Condition: EnableAuth Properties: DesiredDeliveryMediums: - EMAIL UserAttributes: - Name: 'email' Value: !Ref AdminEmail Username: 'Admin' UserPoolId: !Ref UserPool AdminToAdmins: Type: 'AWS::Cognito::UserPoolUserToGroupAttachment' Condition: EnableAuth Properties: GroupName: !Ref Admins Username: !Ref AdminUser UserPoolId: !Ref UserPool ##Create Cognito IdentityPool for Authorization and associate the UserPool client with it IdentityPool: Type: 'AWS::Cognito::IdentityPool' Properties: AllowClassicFlow: false AllowUnauthenticatedIdentities: true CognitoIdentityProviders: - ClientId: !Ref UserPoolClient ProviderName: !Sub - 'cognito-idp.${region}.amazonaws.com/${client}' - region: !Ref 'AWS::Region' client: !Ref UserPool UserPoolClient: Type: 'AWS::Cognito::UserPoolClient' Properties: UserPoolId: !Ref UserPool ##Attach Auth/UnAuth roles for to ID Pool IdentityPoolRoleAttachment: Type: 'AWS::Cognito::IdentityPoolRoleAttachment' Properties: IdentityPoolId: !Ref IdentityPool Roles: 'authenticated': !GetAtt IDPoolAuthRole.Arn 'unauthenticated': !GetAtt IDPoolUnauthRole.Arn ##Role to be used as Media role for the Identity Pool IDPoolAuthRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Sid: '' 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 - Effect: Allow Principal: Service: amplify.amazonaws.com Action: sts:AssumeRole ##Role to be used as Unauth role for the Identity Pool IDPoolUnauthRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Sid: '' 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': unauthenticated - Effect: Allow Principal: Service: amplify.amazonaws.com Action: sts:AssumeRole ## Role to be used by the repository MediaRepositoryAssumeRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Sid: '' 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 - Effect: Allow Principal: Service: amplify.amazonaws.com Action: sts:AssumeRole Policies: - PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Resource: - !GetAtt - Repository - Arn Action: - 'codecommit:GitPull' PolicyName: MediaRepositoryExecutionPolicy ##The role to be assumed by the application using sts_assume_role MediaAppCredsRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Sid: '' 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 - Effect: Allow Principal: Service: amplify.amazonaws.com Action: sts:AssumeRole - Effect: Allow Principal: AWS: - !GetAtt IDPoolAuthRole.Arn - !Join - '' - - 'arn:aws:sts::' - !Ref 'AWS::AccountId' - ':assumed-role/' - !Ref IDPoolAuthRole - '/CognitoIdentityCredentials' - !GetAtt IDPoolAuthRole.Arn - !Join - '' - - 'arn:aws:sts::' - !Ref 'AWS::AccountId' - ':assumed-role/' - !Ref IDPoolUnauthRole - '/CognitoIdentityCredentials' Action: 'sts:AssumeRole' Policies: - PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Resource: !Sub - 'arn:aws:kendra:${region}:${account}:index/${index}' - region: !Ref 'AWS::Region' account: !Ref 'AWS::AccountId' index: !Ref KendraIndexId Action: - 'kendra:DescribeIndex' - 'kendra:SubmitFeedback' - 'kendra:ListDataSources' - 'kendra:Query' - Effect: Allow Resource: !Split - ',' - !Sub - 'arn:aws:s3:::${inner}/*' - inner: !Join - '/*,arn:aws:s3:::' - !Ref MediaBucketNames Action: - 's3:GetObject' PolicyName: AWSMediaAppCredsPolicy ##Create CodeCommit Repository for the code of the application Repository: Type: 'AWS::CodeCommit::Repository' Properties: Code: BranchName: main S3: Bucket: '' Key: !Join - '' - - '' - '' RepositoryName: !Join - '' - - !Ref 'AWS::StackName' - '-Repo' ##Create an App for our application in the Amplify Console AmplifyApp: Type: 'AWS::Amplify::App' Properties: BuildSpec: |- version: 1 frontend: phases: preBuild: commands: - npm install build: commands: - npm run build - REACT_APP_INDEX_ID=$REACT_APP_INDEX_ID - REACT_APP_REGION=$REACT_APP_REGION - REACT_APP_PROJECT_REGION=$REACT_APP_PROJECT_REGION - REACT_APP_IDENTITY_POOL_ID=$REACT_APP_IDENTITY_POOL_ID - REACT_APP_COGNITO_REGION=$REACT_APP_COGNITO_REGION - REACT_APP_USER_POOL_ID=$REACT_APP_USER_POOL_ID - REACT_APP_WEB_CLIENT_ID=$REACT_APP_WEB_CLIENT_ID - REACT_APP_ROLE_ARN=$REACT_APP_ROLE_ARN artifacts: baseDirectory: build files: - '**/*' cache: paths: - node_modules/**/* EnvironmentVariables: - Name: REACT_APP_COGNITO_REGION Value: !Ref 'AWS::Region' - Name: REACT_APP_IDENTITY_POOL_ID Value: !Ref IdentityPool - Name: REACT_APP_INDEX_ID Value: !Ref KendraIndexId - Name: REACT_APP_PROJECT_REGION Value: !Ref 'AWS::Region' - Name: REACT_APP_REGION Value: !Ref 'AWS::Region' - Name: REACT_APP_USER_POOL_ID Value: !Ref UserPool - Name: REACT_APP_WEB_CLIENT_ID Value: !Ref UserPoolClient - Name: REACT_APP_ROLE_ARN Value: !GetAtt MediaAppCredsRole.Arn - Name: REACT_APP_ENABLE_AUTH Value: !If [EnableAuth, 'true', 'false'] - Name: REACT_APP_ENABLE_GUEST Value: !Ref EnableGuestUser - Name: REACT_APP_ENABLE_ACCESSTOKENS Value: !Ref EnableAccessTokens IAMServiceRole: !GetAtt MediaRepositoryAssumeRole.Arn Name: !Join - '' - - !Ref 'AWS::StackName' - '-App' Repository: !GetAtt - Repository - CloneUrlHttp ##Create a branch for the App to be built AmplifyBranch: Type: 'AWS::Amplify::Branch' Properties: AppId: !GetAtt - AmplifyApp - AppId EnableAutoBuild: true BranchName: main MediaLambdaRole: 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 Policies: - PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Resource: '*' Action: - 'amplify:*' PolicyName: MediaLambdaPolicy BuildTriggerLambda: Type: AWS::Lambda::Function Properties: Handler: lambda_function.lambda_handler Runtime: python3.8 Role: !GetAtt 'MediaLambdaRole.Arn' Timeout: 300 Code: S3Bucket: '' S3Key: !Join - '' - - '' - '' Environment: Variables: APP_ID: !GetAtt AmplifyApp.AppId BuildTrigger: Type: Custom::BuildTrigger DependsOn: - AmplifyApp - AmplifyBranch - MediaAppCredsRole Properties: ServiceToken: !GetAtt BuildTriggerLambda.Arn Param1: '' Param2: '' Param3: !Ref KendraIndexId Param4: !Ref MediaBucketNames Param5: !Ref EnableAccessTokens Param6: !Ref EnableGuestUser Param7: !Ref AdminEmail TokenEnablerLambdaRole: Type: AWS::IAM::Role Condition: EnableAccess 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 Policies: - PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Resource: !Sub - 'arn:aws:kendra:${region}:${account}:index/${index}*' - region: !Ref 'AWS::Region' account: !Ref 'AWS::AccountId' index: !Ref KendraIndexId Action: - 'kendra:*' PolicyName: TokenEnablerLambdaPolicy TokenEnablerLambda: Type: AWS::Lambda::Function Condition: EnableAccess Properties: Handler: lambda_function.lambda_handler Runtime: python3.8 Role: !GetAtt 'TokenEnablerLambdaRole.Arn' Timeout: 900 MemorySize: 1024 Code: S3Bucket: '' S3Key: !Join - '' - - '' - '' Environment: Variables: INDEX_ID: !Ref KendraIndexId SIGNING_KEY_URL: !Join - '' - - 'https://cognito-idp.' - !Ref 'AWS::Region' - '.amazonaws.com/' - !Ref UserPool - '/.well-known/jwks.json' TokenEnabler: Type: Custom::TokenEnabler Condition: EnableAccess DependsOn: - AmplifyApp Properties: ServiceToken: !GetAtt TokenEnablerLambda.Arn Param1: '' Param2: '' Param3: !Ref KendraIndexId Param4: !Join - '' - - 'https://cognito-idp.' - !Ref 'AWS::Region' - '.amazonaws.com/' - !Ref UserPool - '/.well-known/jwks.json' Parameters: KendraIndexId: Type: String MediaBucketNames: Type: CommaDelimitedList Default: "" Description: >- (Required) A comma-delimited list of media bucket names - may include wildcards. (Fetch this value from the CFN output for the corresponding Indexer). Needed to support presigned URLs used to access media files contained in search results. AdminEmail: Type: String Description: 'To enable authentication please provide a valid email address for the admin user. This email address will be used for setting the admin password. This email will receive the temporary password for the admin user.' AllowedPattern: "(^$|^.+\\@.+\\..+)" Default: '' ConstraintDescription: 'Must be valid email address eg. johndoe@example.com' EnableGuestUser: Type: String Default: 'false' AllowedValues: ['true', 'false'] Description: 'Set true to enable using the search application without logging in' EnableAccessTokens: Type: String Default: 'false' AllowedValues: ['true', 'false'] Description: 'Set true to enable use of Cognito user pool access tokens in the Kendra index' Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Kendra search webapp parameters Parameters: - KendraIndexId - MediaBucketNames - Label: default: Authentication and access control parameters Parameters: - AdminEmail - EnableGuestUser - EnableAccessTokens Conditions: EnableAuth: !Not - !Equals - !Ref AdminEmail - '' EnableAccess: !Equals - !Ref EnableAccessTokens - 'true' Outputs: MediaSearchFinderURL: Value: !Join - '' - - 'https://main.' - !GetAtt AmplifyApp.DefaultDomain CognitoUserPool: Value: !Ref UserPool CognitoSigningKeyURL: Value: !Join - '' - - 'https://cognito-idp.' - !Ref 'AWS::Region' - '.amazonaws.com/' - !Ref UserPool - '/.well-known/jwks.json'