AWSTemplateFormatVersion: "2010-09-09"
Description: Template to create an IAM Role with an attached policy that provides all necessary permissions for Artillery.io to run distributed tests on AWS Lambda. By default the IAM role is configured to trust your AWS account, meaning it will allow any AWS principal (e.g. IAM User, IAM Role) to assume it. You can restrict the role to allow only by a specific IAM user or role to assume it by filling out the appropriate parameter value below.

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "Restrict to specific IAM User (optional)"
        Parameters:
          - User
      - Label:
          default: "Restrict to specific IAM Role (optional)"
        Parameters:
          - Role
    ParameterLabels:
      User:
        default: "IAM user name or ARN"
      Role:
        default: "IAM role name or ARN"

Parameters:

  User:
    Type: String
    Default: ""
    Description: Use when you want to allow the created role to be assumed only by a specific IAM user (by default any user, role or service from your account will be allowed to assume it). Provide the user name or ARN.

  Role:
    Type: String
    Default: ""
    Description: Use when you want to allow the created role to be assumed only by a specific IAM role (by default any user, role or service from your account will be allowed to assume it). Provide the role name or ARN.

Conditions:
  ShouldTrustAccount:
    !And 
      - !Equals [!Ref User, ""]
      - !Equals [!Ref Role, ""]
  ShouldTrustUser:
      !Not [!Equals [!Ref User, ""]]
  IsUserArn:
      !Equals [!Select [0, !Split [":", !Ref User]], "arn"]
  ShouldTrustRole:
      !Not [!Equals [!Ref Role, ""]]
  IsRoleArn:
      !Equals [!Select [0, !Split [":", !Ref Role]], "arn"]



Resources:
  ArtilleryDistributedTestingLambdaRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: "ArtilleryDistributedTestingLambdaRole"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              AWS: [
                !If [ShouldTrustAccount, !Ref "AWS::AccountId", !Ref "AWS::NoValue"],
                !If [ShouldTrustUser, !If [IsUserArn, !Ref User, !Sub "arn:aws:iam::${AWS::AccountId}:user/${User}"], !Ref "AWS::NoValue"],
                !If [ShouldTrustRole, !If [IsRoleArn, !Ref Role, !Sub "arn:aws:iam::${AWS::AccountId}:role/${Role}"], !Ref "AWS::NoValue"]
              ]
            Action: ["sts:AssumeRole"]
            
      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 ArtilleryDistributedTestingLambdaRole.Arn
