# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 AWSTemplateFormatVersion: '2010-09-09' Description: (%%SOLUTION_ID%%-credmgr) - The AWS CloudFormation template for deployment of the AWS Cloud Migration Factory Credential Manager module (Version %%VERSION%%) Parameters: CodeBucket: # Upload Code in this bucket Description: S3 bucket where all the code reside Type: String KeyPrefix: Description: S3 key Prefix where all the code reside Type: String AdminAPI: Type: String Default: '' Description: API Gateway ID not URL, this can be found in the API Gateway APIs table. AdminAPIRootResourceId: Type: String Default: '' Description: AdminAPI root resource ID. APIResourceAdmin: Type: String Default: '' AdminAuthorizer: Type: String Default: '' ToolsAPI: Type: String Default: '' Description: API Gateway ID not URL, this can be found in the API Gateway APIs table. ToolsAPIRootResourceId: Type: String Default: '' Description: ToolsAPI root resource ID. ToolsAuthorizer: Type: String Default: '' Description: Cognito Authorizer ID for ToolsAPI. RoleDynamoDBTableArn: Type: String PolicyDynamoDBTableArn: Type: String LambdaLayerStdPythonLibs: Type: String LambdaLayerMFPolicyLib: Type: String CORS: Type: String Resources: AdminAPIDeploy: Type: AWS::ApiGateway::Deployment DependsOn: - APIMethodCredentialManagerPost - APIMethodCredentialManagerPut - APIMethodCredentialManagerDelete - APIMethodCredentialManagerGet - APIAdminMethodCredentialManagerOPTIONS - APIToolsMethodCredentialManagerOPTIONS Properties: RestApiId: !Ref 'AdminAPI' StageName: prod Metadata: cfn_nag: rules_to_suppress: - id: W68 reason: As this is for internal use only tool, and very low number of API calls, no usage plan is required - id: W45 reason: StageDescription already exists for this Deployment. Re-deploying so that new resource is deployed to API. APIResourceCredentialManagerPath: Type: AWS::ApiGateway::Resource Properties: RestApiId: !Ref 'AdminAPI' ParentId: !Ref 'APIResourceAdmin' PathPart: credentialmanager APIAdminMethodCredentialManagerOPTIONS: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref 'AdminAPI' ResourceId: !Ref 'APIResourceCredentialManagerPath' HttpMethod: OPTIONS AuthorizationType: NONE MethodResponses: - StatusCode: '200' ResponseModels: application/json: Empty ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': false 'method.response.header.Access-Control-Allow-Methods': false 'method.response.header.Access-Control-Allow-Headers': false Integration: Type: MOCK IntegrationResponses: - StatusCode: '200' ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': !Sub "'${CORS}'" 'method.response.header.Access-Control-Allow-Methods': '''DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT''' 'method.response.header.Access-Control-Allow-Headers': '''Content-Type,X-Amz-Date,Authorization,Authorization-Access,X-Api-Key,X-Amz-Security-Token,X-Requested-With,Accept,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Allow-Headers''' ResponseTemplates: application/json: '' RequestTemplates: application/json: '{"statusCode": 200}' APIMethodCredentialManagerPost: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref 'AdminAPI' ResourceId: !Ref 'APIResourceCredentialManagerPath' HttpMethod: POST AuthorizationType: CUSTOM AuthorizerId: !Ref 'AdminAuthorizer' MethodResponses: - StatusCode: '200' ResponseModels: application/json: Empty ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': false Integration: Type: AWS_PROXY IntegrationHttpMethod: POST IntegrationResponses: - StatusCode: '200' ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': !Sub "'${CORS}'" Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CredentialManager.Arn}/invocations' APIMethodCredentialManagerPut: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref 'AdminAPI' ResourceId: !Ref 'APIResourceCredentialManagerPath' HttpMethod: PUT AuthorizationType: CUSTOM AuthorizerId: !Ref 'AdminAuthorizer' MethodResponses: - StatusCode: '200' ResponseModels: application/json: Empty ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': false Integration: Type: AWS_PROXY IntegrationHttpMethod: POST IntegrationResponses: - StatusCode: '200' ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': !Sub "'${CORS}'" Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CredentialManager.Arn}/invocations' APIMethodCredentialManagerDelete: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref 'AdminAPI' ResourceId: !Ref 'APIResourceCredentialManagerPath' HttpMethod: DELETE AuthorizationType: CUSTOM AuthorizerId: !Ref 'AdminAuthorizer' MethodResponses: - StatusCode: '200' ResponseModels: application/json: Empty ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': false Integration: Type: AWS_PROXY IntegrationHttpMethod: POST IntegrationResponses: - StatusCode: '200' ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': !Sub "'${CORS}'" Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CredentialManager.Arn}/invocations' APIMethodCredentialManagerGet: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref 'AdminAPI' ResourceId: !Ref 'APIResourceCredentialManagerPath' HttpMethod: GET AuthorizationType: CUSTOM AuthorizerId: !Ref 'AdminAuthorizer' MethodResponses: - StatusCode: '200' ResponseModels: application/json: Empty ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': false Integration: Type: AWS_PROXY IntegrationHttpMethod: POST IntegrationResponses: - StatusCode: '200' ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': !Sub "'${CORS}'" Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CredentialManager.Arn}/invocations' ToolsAPIResourceCredentialManagerPath: Type: AWS::ApiGateway::Resource Properties: RestApiId: !Ref 'ToolsAPI' ParentId: !Ref 'ToolsAPIRootResourceId' PathPart: credentialmanager ToolsAPIMethodCredentialManagerGet: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref 'ToolsAPI' ResourceId: !Ref 'ToolsAPIResourceCredentialManagerPath' HttpMethod: GET AuthorizationType: COGNITO_USER_POOLS AuthorizerId: !Ref 'ToolsAuthorizer' MethodResponses: - StatusCode: '200' ResponseModels: application/json: Empty ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': false Integration: Type: AWS_PROXY IntegrationHttpMethod: POST IntegrationResponses: - StatusCode: '200' ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': !Sub "'${CORS}'" Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CredentialManager.Arn}/invocations' APIToolsMethodCredentialManagerOPTIONS: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref 'ToolsAPI' ResourceId: !Ref 'ToolsAPIResourceCredentialManagerPath' HttpMethod: OPTIONS AuthorizationType: NONE MethodResponses: - StatusCode: '200' ResponseModels: application/json: Empty ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': false 'method.response.header.Access-Control-Allow-Methods': false 'method.response.header.Access-Control-Allow-Headers': false Integration: Type: MOCK IntegrationResponses: - StatusCode: '200' ResponseParameters: 'method.response.header.Access-Control-Allow-Origin': !Sub "'${CORS}'" 'method.response.header.Access-Control-Allow-Methods': '''DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT''' 'method.response.header.Access-Control-Allow-Headers': '''Content-Type,X-Amz-Date,Authorization,Authorization-Access,X-Api-Key,X-Amz-Security-Token,X-Requested-With,Accept,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Allow-Headers''' ResponseTemplates: application/json: '' RequestTemplates: application/json: '{"statusCode": 200}' ToolsAPIDeploy: Type: AWS::ApiGateway::Deployment DependsOn: - ToolsAPIResourceCredentialManagerPath - ToolsAPIMethodCredentialManagerGet Properties: RestApiId: !Ref 'ToolsAPI' StageName: prod Metadata: cfn_nag: rules_to_suppress: - id: W68 reason: As this is for internal use only tool, and very low number of API calls, no usage plan is required - id: W45 reason: StageDescription already exists for this Deployment. Re-deploying so that new resource is deployed to API. CredentialManager: Type: AWS::Lambda::Function Properties: Code: S3Bucket: !Ref CodeBucket S3Key: !Join ["/", [!Ref KeyPrefix, "lambda_credential_manager.zip"]] Description: Code to list your secret from AWS Secret Manager Handler: CredentialManager.lambda_handler Role: !GetAtt 'CredentialManagerRole.Arn' Environment: Variables: region: !Ref "AWS::Region" cors: !Ref CORS Timeout: 30 Runtime: python3.10 Layers: - !Ref LambdaLayerStdPythonLibs - !Ref LambdaLayerMFPolicyLib Metadata: cfn_nag: rules_to_suppress: - id: W89 reason: "Deploy in AWS managed environment provides more flexibility for this solution" - id: W92 reason: "Reserve Concurrent Execution is not needed for this solution" CredentialManagerRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com Policies: - PolicyName: LambdaRolePolicy PolicyDocument: Version: '2012-10-17' Statement: - Action: - 'dynamodb:Scan' - 'dynamodb:GetItem' - 'dynamodb:Query' Effect: Allow Resource: - !Join [ '', [ !Ref RoleDynamoDBTableArn, '*' ] ] - !Join [ '', [ !Ref PolicyDynamoDBTableArn, '*' ] ] ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/SecretsManagerReadWrite CredentialManagerPermissionAdmin: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction Principal: apigateway.amazonaws.com FunctionName: !Ref 'CredentialManager' SourceArn: !Sub - arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*/* - __Stage__: '*' __ApiId__: !Ref 'AdminAPI' CredentialManagerPermissionTools: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction Principal: apigateway.amazonaws.com FunctionName: !Ref 'CredentialManager' SourceArn: !Sub - arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*/* - __Stage__: '*' __ApiId__: !Ref 'ToolsAPI'