AWSTemplateFormatVersion: '2010-09-09'
Description: Creates an ArtilleryGitHubOIDCForLambdaRole IAM role with permissions needed to run Artillery Lambda tests from a specified GitHub repository. An OIDC identity provider for Github will also be created if it is not already present in the account.


Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "GitHub"
        Parameters:
          - GitHubRepository
          - GitHubBranch
      - Label:
          default: "AWS IAM"
        Parameters:
          - GitHubOIDCProviderExists

    ParameterLabels:
      GitHubRepository:
        default: "GitHub repository"
      GitHubBranch:
        default: "GitHub branch"
      GitHubOIDCProviderExists:
        default: "GitHub OIDC identity provider already created for the account?"

Parameters:
  GitHubRepository:
    Type: String
    Default: ""
    Description: The GitHub repository (orgname/reponame) to be allowed to assume the created IAM role using OIDC (e.g. "artilleryio/artillery").

  GitHubBranch:
    Type: String
    Default: "*"
    Description: (Optional) Use when you want to allow only a specific branch within the specified Github repository to assume this IAM role using OIDC (e.g. "main"). If not set, defaults to "*" (all branches). 

  GitHubOIDCProviderExists:
    Type: String
    Default: 'No'
    AllowedValues:
      - 'Yes'
      - 'No'
    Description: This will let CloudFormation know whether it needs to create the provider. (If it exists, can be found at Services -> IAM -> Identity providers as 'token.actions.githubusercontent.com').

Conditions:
  IsGHRepoSet:
    !Not [!Equals [!Ref GitHubRepository, ""]]

  CreateOIDCProvider:
    !Equals [!Ref GitHubOIDCProviderExists, "No"]

Resources:
  GitHubOIDCProvider:
    Type: AWS::IAM::OIDCProvider
    Condition: CreateOIDCProvider
    Properties:
      Url: "https://token.actions.githubusercontent.com"
      ClientIdList:
        - "sts.amazonaws.com"
      ThumbprintList:
        - "6938fd4d98bab03faadb97b34396831e3780ee11"


  ArtilleryGitHubOIDCForLambdaRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: "ArtilleryGitHubOIDCForLambdaRole"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Federated: 
                Fn::If:
                  - CreateOIDCProvider
                  - !Ref GitHubOIDCProvider
                  - !Ref GitHubOIDCProviderArn
            Action: "sts:AssumeRoleWithWebIdentity"
            Condition: {
              StringEquals:
                {
                  "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                },
              StringLike:
                {
                  "token.actions.githubusercontent.com:sub": !Sub "repo:${GitHubRepository}:${GitHubBranch}"
                }
            }
      Path: "/"
      Policies:
        - PolicyName: ArtilleryDistributedTestingLambdaPolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Sid: CreateOrGetLambdaRole
                Effect: Allow
                Action:
                  - iam:CreateRole
                  - iam:GetRole
                  - iam:PassRole
                  - iam:AttachRolePolicy
                Resource: !Sub "arn:aws:iam::${AWS::AccountId}:role/artilleryio-default-lambda-role-*"
              - Sid: CreateLambdaPolicy
                Effect: Allow
                Action:
                  - iam:CreatePolicy
                Resource: !Sub "arn:aws:iam::${AWS::AccountId}:policy/artilleryio-lambda-policy-*"
              - Sid: SQSPermissions
                Effect: Allow
                Action:
                  - sqs:*
                Resource: !Sub "arn:aws:sqs:*:${AWS::AccountId}:artilleryio*"
              - Sid: SQSListQueues
                Effect: Allow
                Action:
                  - sqs:ListQueues
                Resource: "*"
              - Sid: LambdaPermissions
                Effect: Allow
                Action:
                  - lambda:InvokeFunction
                  - lambda:CreateFunction
                  - lambda:DeleteFunction
                  - lambda:GetFunctionConfiguration
                Resource: !Sub "arn:aws:lambda:*:${AWS::AccountId}:function:artilleryio-*"
              - Sid: EcrPullImagePermissions
                Effect: Allow
                Action:
                  - ecr:GetDownloadUrlForLayer
                  - ecr:BatchGetImage
                Resource: "arn:aws:ecr:*:248481025674:repository/artillery-worker"
              - Sid: S3Permissions
                Effect: Allow
                Action:
                  - s3:CreateBucket
                  - s3:DeleteObject
                  - s3:GetObject
                  - s3:PutObject
                  - s3:ListBucket
                  - s3:GetLifecycleConfiguration
                  - s3:PutLifecycleConfiguration
                Resource:
                  - !Sub "arn:aws:s3:::artilleryio-test-data-*"
                  - !Sub "arn:aws:s3:::artilleryio-test-data-*/*"

Outputs:
  RoleArn:
    Description: ARN of the IAM Role for Artillery.io Lambda functions
    Value: !GetAtt ArtilleryGitHubOIDCForLambdaRole.Arn
  OIDCProviderArn:
    Condition: CreateOIDCProvider
    Description: "ARN of the newly created OIDC provider"
    Value: !Ref GitHubOIDCProvider