Resources:
  QuiltCloudFormationServiceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: root
            Effect: Allow
            Principal:
              Service: cloudformation.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: QuiltServiceRolePolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - apigateway:DELETE
                  - apigateway:GET
                  - apigateway:PATCH
                  - apigateway:POST
                  - apigateway:PUT
                  - apigateway:SetWebACL
                  - apigateway:UpdateRestApiPolicy
                  - appsync:SetWebACL
                  - apprunner:AssociateWebAcl
                  - apprunner:DescribeWebAclForService
                  - apprunner:DisassociateWebAcl
                  - athena:CreateWorkGroup
                  - athena:DeleteWorkGroup
                  - athena:GetWorkGroup
                  - athena:TagResource
                  - autoscaling:CreateAutoScalingGroup
                  - autoscaling:DeleteAutoScalingGroup
                  - autoscaling:DescribeAutoScalingGroups
                  - autoscaling:DescribeAutoScalingInstances
                  - autoscaling:DescribeLifecycleHooks
                  - autoscaling:DescribeNotificationConfigurations
                  - autoscaling:DescribeScalingActivities
                  - autoscaling:UpdateAutoScalingGroup
                  - cloudtrail:AddTags
                  - cloudtrail:CreateTrail
                  - cloudtrail:DeleteTrail
                  - cloudtrail:DescribeTrails
                  - cloudtrail:GetEventSelectors
                  - cloudtrail:GetInsightSelectors
                  - cloudtrail:GetTrail
                  - cloudtrail:GetTrailStatus
                  - cloudtrail:ListTags
                  - cloudtrail:PutEventSelectors
                  - cloudtrail:StartLogging
                  - cognito-idp:AssociateWebACL
                  - cognito-idp:DisassociateWebACL
                  - cognito-idp:GetWebACLForResource
                  - ec2:AssociateRouteTable
                  - ec2:AssociateVerifiedAccessInstanceWebAcl
                  - ec2:AttachInternetGateway
                  - ec2:AuthorizeSecurityGroupEgress
                  - ec2:AuthorizeSecurityGroupIngress
                  - ec2:CreateInternetGateway
                  - ec2:CreateLaunchTemplate
                  - ec2:CreateRoute
                  - ec2:CreateRouteTable
                  - ec2:CreateSecurityGroup
                  - ec2:CreateSubnet
                  - ec2:CreateTags
                  - ec2:CreateVpc
                  - ec2:DeleteInternetGateway
                  - ec2:DeleteLaunchTemplate
                  - ec2:DeleteNetworkInterface
                  - ec2:DeleteRoute
                  - ec2:DeleteRouteTable
                  - ec2:DeleteSecurityGroup
                  - ec2:DeleteSubnet
                  - ec2:DeleteVpc
                  - ec2:DescribeAccountAttributes
                  - ec2:DescribeAvailabilityZones
                  - ec2:DescribeImages
                  - ec2:DescribeInstances
                  - ec2:DescribeInternetGateways
                  - ec2:DescribeLaunchTemplateVersions
                  - ec2:DescribeLaunchTemplates
                  - ec2:DescribeNetworkAcls
                  - ec2:DescribeNetworkInterfaces
                  - ec2:DescribeRouteTables
                  - ec2:DescribeSecurityGroupRules
                  - ec2:DescribeSecurityGroups
                  - ec2:DescribeSubnets
                  - ec2:DescribeVpcAttribute
                  - ec2:DescribeVpcs
                  - ec2:DetachInternetGateway
                  - ec2:DetachNetworkInterface
                  - ec2:DisassociateRouteTable
                  - ec2:DisassociateVerifiedAccessInstanceWebAcl
                  - ec2:GetVerifiedAccessInstanceWebAcl
                  - ec2:ModifyVpcAttribute
                  - ec2:RevokeSecurityGroupEgress
                  - ec2:RunInstances
                  - ecr:BatchGetImage
                  - ecr:GetDownloadUrlForLayer
                  - ecs:CreateCluster
                  - ecs:CreateService
                  - ecs:DeleteCluster
                  - ecs:DeleteService
                  - ecs:DeregisterTaskDefinition
                  - ecs:DescribeClusters
                  - ecs:DescribeServices
                  - ecs:RegisterTaskDefinition
                  - ecs:TagResource
                  - ecs:UpdateService
                  - elasticloadbalancing:AddTags
                  - elasticloadbalancing:CreateListener
                  - elasticloadbalancing:CreateLoadBalancer
                  - elasticloadbalancing:CreateRule
                  - elasticloadbalancing:CreateTargetGroup
                  - elasticloadbalancing:DeleteListener
                  - elasticloadbalancing:DeleteLoadBalancer
                  - elasticloadbalancing:DeleteRule
                  - elasticloadbalancing:DeleteTargetGroup
                  - elasticloadbalancing:DescribeListeners
                  - elasticloadbalancing:DescribeLoadBalancerAttributes
                  - elasticloadbalancing:DescribeLoadBalancers
                  - elasticloadbalancing:DescribeRules
                  - elasticloadbalancing:DescribeTags
                  - elasticloadbalancing:DescribeTargetGroupAttributes
                  - elasticloadbalancing:DescribeTargetGroups
                  - elasticloadbalancing:DescribeTargetHealth
                  - elasticloadbalancing:ModifyLoadBalancerAttributes
                  - elasticloadbalancing:ModifyTargetGroupAttributes
                  - elasticloadbalancing:SetWebAcl
                  - es:AddTags
                  - es:CreateElasticsearchDomain
                  - es:DeleteElasticsearchDomain
                  - es:DescribeElasticsearchDomain
                  - es:UpdateDomainConfig
                  - es:UpdateElasticsearchDomainConfig
                  - events:DeleteRule
                  - events:DescribeRule
                  - events:ListTargetsByRule
                  - events:PutRule
                  - events:PutTargets
                  - events:RemoveTargets
                  - events:TagResource
                  - firehose:CreateDeliveryStream
                  - firehose:DeleteDeliveryStream
                  - firehose:DescribeDeliveryStream
                  - firehose:ListTagsForDeliveryStream
                  - firehose:TagDeliveryStream 
                  - glue:CreateDatabase
                  - glue:CreateTable
                  - glue:DeleteDatabase
                  - glue:DeleteTable
                  - glue:TagResource
                  - iam:AddRoleToInstanceProfile
                  - iam:AttachRolePolicy
                  - iam:CreateInstanceProfile
                  - iam:CreatePolicy
                  - iam:CreatePolicyVersion
                  - iam:CreateRole
                  - iam:CreateServiceLinkedRole
                  - iam:DeleteInstanceProfile
                  - iam:DeletePolicy
                  - iam:DeletePolicyVersion
                  - iam:DeleteRole
                  - iam:DeleteRolePolicy
                  - iam:DetachRolePolicy
                  - iam:GetInstanceProfile
                  - iam:GetPolicy
                  - iam:GetRole
                  - iam:GetRolePolicy
                  - iam:ListPolicyVersions
                  - iam:PassRole
                  - iam:PutRolePolicy
                  - iam:RemoveRoleFromInstanceProfile
                  - iam:TagRole
                  - iam:TagPolicy
                  - kms:CreateGrant
                  - kms:CreateKey
                  - kms:Decrypt
                  - kms:DescribeKey
                  - kms:Encrypt
                  - kms:GenerateDataKey
                  - kms:GetKeyPolicy
                  - kms:GetKeyRotationStatus
                  - kms:ListResourceTags
                  - kms:PutKeyPolicy
                  - kms:ScheduleKeyDeletion
                  - kms:TagResource
                  - lambda:AddPermission
                  - lambda:CreateEventSourceMapping
                  - lambda:CreateFunction
                  - lambda:DeleteEventSourceMapping
                  - lambda:DeleteFunction
                  - lambda:DeleteLayerVersion
                  - lambda:GetEventSourceMapping
                  - lambda:GetFunction
                  - lambda:GetFunctionCodeSigningConfig
                  - lambda:GetFunctionConfiguration
                  - lambda:GetLayerVersion
                  - lambda:GetRuntimeManagementConfig
                  - lambda:InvokeFunction
                  - lambda:PublishLayerVersion
                  - lambda:PublishVersion
                  - lambda:PutFunctionConcurrency
                  - lambda:RemovePermission
                  - lambda:TagResource
                  - lambda:UpdateFunctionCode
                  - lambda:UpdateFunctionConfiguration
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:DeleteLogGroup
                  - logs:DeleteLogStream
                  - logs:DeleteResourcePolicy
                  - logs:DescribeLogGroups
                  - logs:DescribeLogStreams
                  - logs:DescribeResourcePolicies
                  - logs:PutResourcePolicy
                  - logs:PutRetentionPolicy
                  - logs:TagResource
                  - organizations:ListAWSServiceAccessForOrganization
                  - rds:AddTagsToResource
                  - rds:CreateDBInstance
                  - rds:CreateDBSubnetGroup
                  - rds:CreateTenantDatabase
                  - rds:DeleteDBInstance
                  - rds:DeleteDBSubnetGroup
                  - rds:DeleteTenantDatabase
                  - rds:DescribeDBInstances
                  - rds:DescribeDBSubnetGroups
                  - rds:ListTagsForResource
                  - rds:ModifyDBInstance
                  - route53:CreateHostedZone
                  - s3:*  # Stack has this anyway; Canary buckets get Access Denied even with GetObject
                  - secretsmanager:CreateSecret
                  - secretsmanager:TagResource
                  - servicediscovery:CreatePrivateDnsNamespace
                  - servicediscovery:CreateService
                  - servicediscovery:DeleteNamespace
                  - servicediscovery:DeleteService
                  - servicediscovery:GetOperation
                  - servicediscovery:GetService
                  - servicediscovery:TagResource
                  - sns:CreateTopic
                  - sns:DeleteTopic
                  - sns:Get*
                  - sns:Publish  # To publish to CFN notification topic.
                  - sns:SetTopicAttributes 
                  - sns:Subscribe
                  - sns:TagResource
                  - sqs:CreateQueue
                  - sqs:DeleteQueue
                  - sqs:GetQueueAttributes
                  - sqs:GetQueueUrl
                  - sqs:ListDeadLetterSourceQueues
                  - sqs:ListQueues
                  - sqs:ListQueueTags
                  - sqs:SetQueueAttributes
                  - sqs:TagQueue
                  - ssm:AddTagsToResource
                  - ssm:DeleteParameter
                  - ssm:GetParameters
                  - ssm:PutParameter
                  - synthetics:CreateCanary
                  - synthetics:DeleteCanary
                  - synthetics:GetCanary
                  - synthetics:StartCanary
                  - synthetics:StopCanary
                  - synthetics:TagResource
                  - wafv2:AssociateWebACL
                  - wafv2:CreateRegexPatternSet
                  - wafv2:CreateWebACL
                  - wafv2:DeleteRegexPatternSet
                  - wafv2:DeleteWebACL
                  - wafv2:DisassociateWebACL
                  - wafv2:GetRegexPatternSet
                  - wafv2:GetWebACL
                  - wafv2:GetWebACLForResource
                  - wafv2:ListTagsForResource
                  - wafv2:TagResource
                Resource: '*'
Outputs:
  QuiltServiceRoleArn:
    Description: "ARN of the Quilt Service IAM Role"
    Value: !GetAtt QuiltCloudFormationServiceRole.Arn
