Parameters:
  MainAWSAccountId:
    Type: String
    Default: ""
    Description: The Account ID of the Main account containing the Lambda function that will trigger the CI CodeBuild project.
  GitHubOrg:
    Type: String
    Default: "aws"
    Description: The GitHub organization to use for the repository.
  GitHubRepositoryName:
    Description: The name of the GitHub repository to create the role template in and to use for the CodeBuild.
    Type: String
    Default: "aws-dotnet-deploy"
  OIDCProviderArn:
    Description: Arn for the GitHub OIDC Provider.  Leave blank to create a new one or provide an existing Provider.  There can only be one GitHub OIDC Provider per GitHubOrg per AWS Account.  Example arn:aws:iam::665544332211:oidc-provider/token.actions.githubusercontent.com
    Default: ""
    Type: String
  CodeBuildProjectName:
    Description: Name of the CodeBuild project.
    Default: "aws-dotnet-deploy-ci"
    Type: String
  TestRunnerTrustRoleName:
    Description: Name of the role to allow GitHub to execute CodeBuild jobs.
    Default: "aws-dotnet-deploy-ci-role"
    Type: String


Conditions:
  CreateOIDCProvider: !Equals
    - !Ref OIDCProviderArn
    - ""

Resources:
  TestRunnerTrustRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref TestRunnerTrustRoleName
      MaxSessionDuration: 7200
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Sub arn:aws:iam::${MainAWSAccountId}:root
            Action: sts:AssumeRole
          - Effect: Allow
            Action: sts:AssumeRoleWithWebIdentity
            Principal:
              Federated: !If
                - CreateOIDCProvider
                - !Ref GithubOidc
                - !Ref OIDCProviderArn
            Condition:
              StringLike:
                token.actions.githubusercontent.com:sub: !Sub repo:${GitHubOrg}/${GitHubRepositoryName}:*
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-OIDC-Policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - codebuild:StartBuild
                  - codebuild:BatchGetBuilds
                  - codebuild:BatchGetProjects
                  - codebuild:ListBuildsForProject
                Resource:
                  - !Sub arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:project/${CodeBuildProjectName}
              - Effect: Allow
                Action:
                  - logs:GetLogEvents
                Resource:
                  - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildProjectName}:*
              - Effect: Allow
                Action:
                  - sts:GetCallerIdentity
                Resource: 
                  - '*'

  GithubOidc:
    Type: AWS::IAM::OIDCProvider
    Condition: CreateOIDCProvider
    Properties:
      Url: https://token.actions.githubusercontent.com
      ClientIdList:
        - sts.amazonaws.com
      ThumbprintList:
        - 6938fd4d98bab03faadb97b34396831e3780aea1
        - 1c58a3a8518e8759bf075b76b750d4f2df264fcd
  CodeBuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
      ConcurrentBuildLimit: 1
      Name: !Sub ${CodeBuildProjectName}
      ServiceRole: !GetAtt CodeBuildProjectRole.Arn
      Environment:
        PrivilegedMode: true
        ComputeType: BUILD_GENERAL1_LARGE
        Type: LINUX_CONTAINER
        ImagePullCredentialsType: CODEBUILD
        Image: aws/codebuild/standard:5.0
      Source:
        Type: GITHUB
        Location: !Sub https://github.com/${GitHubOrg}/${GitHubRepositoryName}
        BuildSpec: buildtools/ci.buildspec.yml
      Artifacts:
        Type: NO_ARTIFACTS
      TimeoutInMinutes: 120

  CodeBuildProjectRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${CodeBuildProjectName}-codebuild-service-role
      MaxSessionDuration: 7200
      AssumeRolePolicyDocument:
        Statement:
        - Action: ['sts:AssumeRole']
          Effect: Allow
          Principal:
            Service: [codebuild.amazonaws.com]
        Version: '2012-10-17'
      Path: /
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-codebuild-service-role-policy"
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Action:
                - '*'
                Effect: Allow
                Resource:
                  - '*'

Outputs:
  TestRunnerTrustRole:
    Value: !GetAtt TestRunnerTrustRole.Arn
  CodeBuildProjectName:
    Value: !Sub ${CodeBuildProjectName}