AWSTemplateFormatVersion: 2010-09-09
Description: >
    This template creates a CodeCommit repo and initializes it with this
    project sources. It uses CodeBuild and a custom resource to git push
    the files into the repo.

Parameters:
    CodeCommitRepoName:
        Type: String
        Description: Name of CodeCommit repository name to be created.
        Default: lex-web-ui
        MinLength: 1
        MaxLength: 100
        AllowedPattern: '^[\w\.-]+$'
        ConstraintDescription: Alphanumeric, dot and dash.

    CodeBuildName:
        Type: String
        Description: CodeBuild project used to initialize the code repo
        Default: lex-web-ui-init
        MinLength: 2
        MaxLength: 255
        AllowedPattern: '^[A-Za-z0-9][A-Za-z0-9\-_]{1,254}$'
        ConstraintDescription: >
            Should start with Alphanumeric. May contain alphanumeric, undescore
            and dash.

    SourceBucket:
        Description: S3 bucket where the source is located
        Type: String
        Default: aws-bigdata-blog

    SourceObject:
        Description: S3 object zip file containing the project source
        Type: String
        Default: artifacts/aws-lex-web-ui/artifacts/src.zip

    CustomResourceCodeObject:
        Type: String
        Description: >
            S3 object zip file containing Lambda custom resource functions
        Default: artifacts/aws-lex-web-ui/artifacts/custom-resources.zip

    CognitoIdentityPoolId:
        Type: String
        Description: >
            Cognito Identity Pool Id to used in the web app configuration.
        MinLength: 1
        MaxLength: 55
        AllowedPattern: '^[\w-]+:[0-9a-f-]+$'
        ConstraintDescription: >
            Alphanumeric followed by a colum and ending with a hex uuid type.

    BotName:
        Description: >
            Name of Lex bot to be used in the web app configuration.
        Type: String
        MinLength: 2
        MaxLength: 50
        AllowedPattern: '^[a-zA-Z]+((_[a-zA-Z]+)*|([a-zA-Z]+_)*|_)'
        ConstraintDescription: >
            Must conform with the permitted Lex Bot name pattern.

Resources:
    CodeCommitRepo:
        Type: AWS::CodeCommit::Repository
        Properties:
            RepositoryDescription: Lex Web UI
            RepositoryName: !Ref CodeCommitRepoName

    CodeBuild:
        Type: AWS::CodeBuild::Project
        Properties:
            Name: !Ref CodeBuildName
            Description: Used to initialize the Lex Web UI CodeCommit Repo
            Artifacts:
                Type: NO_ARTIFACTS
            Environment:
                Type: LINUX_CONTAINER
                Image: aws/codebuild/nodejs:6.3.1
                ComputeType: BUILD_GENERAL1_SMALL
                EnvironmentVariables:
                    - Name: REPO_URL
                      Value: !GetAtt CodeCommitRepo.CloneUrlHttp
                    - Name: POOL_ID
                      Value: !Ref CognitoIdentityPoolId
                    - Name: BOT_NAME
                      Value: !Ref BotName
            ServiceRole: !GetAtt CodeBuildRole.Arn
            TimeoutInMinutes: 10
            Source:
                Type: S3
                Location: !Sub "${SourceBucket}/${SourceObject}"
                BuildSpec: !Sub |
                    version: 0.1
                    phases:
                        install:
                            commands:
                                - npm install -g n
                                - n stable
                                - npm update -g npm
                        pre_build:
                            commands:
                                - make config
                        build:
                            commands:
                                - aws configure set region "${AWS::Region}"
                                - git config --global user.name 'CodeCommit Init'
                                - git config --global user.email '<>'
                                - git config --global push.default simple
                                - git config --global "credential.https://git-codecommit.${AWS::Region}.amazonaws.com.helper" '!aws codecommit credential-helper $@'
                                - git config --global "credential.https://git-codecommit.${AWS::Region}.amazonaws.com.UseHttpPath" 'true'
                                - git init
                                - git add .
                                - git commit -a -m initial
                                - git remote add origin "${!REPO_URL}"
                                - git push --set-upstream origin master

    # custom resource to start code build project
    CodeBuildStarter:
        Type: Custom::CodeBuildStarter
        Properties:
            ServiceToken: !GetAtt CodeBuildStarterLambda.Arn
            ProjectName: !Ref CodeBuild

    # Lambda function for custom resource
    CodeBuildStarterLambda:
        Type: AWS::Lambda::Function
        Properties:
            Code:
                S3Bucket: !Ref SourceBucket
                S3Key: !Ref CustomResourceCodeObject
            Handler: codebuild-start.handler
            Role: !GetAtt CodeBuildStarterLambdaRole.Arn
            Runtime: python2.7
            Timeout: 120

    CodeBuildRole:
        Type: AWS::IAM::Role
        Properties:
            Path: /
            AssumeRolePolicyDocument:
                Version: 2012-10-17
                Statement:
                    - Principal:
                          Service:
                              - codebuild.amazonaws.com
                      Effect: Allow
                      Action:
                          - sts:AssumeRole
            Policies:
                - PolicyName: CodeCommitGetListPush
                  PolicyDocument:
                      Version: 2012-10-17
                      Statement:
                          - Effect: Allow
                            Action:
                                - codecommit:BatchGetRepositories
                                - codecommit:CreateBranch
                                - codecommit:Get*
                                - codecommit:GitPull
                                - codecommit:GitPush
                                - codecommit:List*
                                - codecommit:UpdateDefaultBranch
                            Resource:
                                - !GetAtt CodeCommitRepo.Arn
                - PolicyName: S3GetObject
                  PolicyDocument:
                      Version: 2012-10-17
                      Statement:
                          - Effect: Allow
                            Action:
                                - s3:GetObject*
                            Resource:
                                - !Sub "arn:aws:s3:::${SourceBucket}/${SourceObject}"
                - PolicyName: CloudWatchLogsCodeBuild
                  PolicyDocument:
                      Version: 2012-10-17
                      Statement:
                          - Effect: Allow
                            Action:
                                - logs:CreateLogGroup
                                - logs:CreateLogStream
                                - logs:PutLogEvents
                            Resource:
                                - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildName}"
                                - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildName}:*"

    CodeBuildStarterLambdaRole:
        Type: AWS::IAM::Role
        Properties:
            Path: /
            AssumeRolePolicyDocument:
                Version: 2012-10-17
                Statement:
                    - Principal:
                          Service:
                              - lambda.amazonaws.com
                      Effect: Allow
                      Action:
                          - sts:AssumeRole
            Policies:
                - PolicyName: LogsForLambda
                  PolicyDocument:
                      Version: 2012-10-17
                      Statement:
                          - Effect: Allow
                            Action:
                                - logs:CreateLogGroup
                                - logs:CreateLogStream
                                - logs:PutLogEvents
                            Resource:
                                - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*"
                                - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*:*"
                - PolicyName: CodeBuildStart
                  PolicyDocument:
                      Version: 2012-10-17
                      Statement:
                          - Effect: Allow
                            Action:
                                - codebuild:StartBuild
                            Resource: !GetAtt CodeBuild.Arn

Outputs:
    CodeCommitRepoUrl:
        Description: CodeCommit repository clone URL
        Value: !GetAtt CodeCommitRepo.CloneUrlHttp

    CodeCommitRepoArn:
        Description: CodeCommit repository clone URL
        Value: !GetAtt CodeCommitRepo.Arn

    CodeCommitRepoName:
        Description: CodeCommit repository name
        Value: !GetAtt CodeCommitRepo.Name
