Description: Create IAM roles to deploy tidbcloud
Parameters:
  # ControlPlane account id
  ControlPlaneAccountId:
    Type: String
    Description: "TiDB Cloud Control Plane AWS Principal"
    Default: "385595570414"
  GithubRunnerGoogleAccountId:
    Type: String
    Description: "The Google Account ID of the GitHub runner for PingCAP"
    Default: "114667344163696279999"
  O11yHostedZoneId:
    Type: String
    Description: "The Route 53 hosted zone ID to manage DNS records for o11y"
  AdditionalO11yHostedZoneIds:
    Type: CommaDelimitedList
    Default: ""
    Description: "Additional o11y hosted zone IDs for multi-region deployments (comma-separated IDs, e.g. Z111AAA,Z222BBB)"
Conditions:
  HasAdditionalO11yZones: !Not [!Equals [!Join [",", !Ref AdditionalO11yHostedZoneIds], ""]]
Resources:
  TiDBCloudSyncImageRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: auto-deploy-sync-image
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Federated: "accounts.google.com"
            Action: sts:AssumeRoleWithWebIdentity
            Condition:
              StringEquals:
                accounts.google.com:aud: !Sub ${GithubRunnerGoogleAccountId}
      Policies:
        - PolicyName: auto-deploy-sync-image-policy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Action:
                  - ecr:GetAuthorizationToken
                Effect: Allow
                Resource:
                  - "*"
                Sid: GetToken
              - Action:
                  - ecr:DescribeRepositories
                Effect: Allow
                Resource:
                  - "*"
                Sid: CheckRepository
              - Action:
                  - ecr:CreateRepository
                  - ecr:TagResource
                Condition:
                  ForAllValues:StringEquals:
                    aws:TagKeys:
                      - ManagedBy
                  StringEquals:
                    aws:RequestTag/ManagedBy: PingCAP
                Effect: Allow
                Resource:
                  - "*"
                Sid: CreateRepository
              - Action:
                  - ecr:BatchCheckLayerAvailability
                  - ecr:BatchGetImage
                  - ecr:InitiateLayerUpload
                  - ecr:UploadLayerPart
                  - ecr:CompleteLayerUpload
                  - ecr:PutImage
                Condition:
                  StringEquals:
                    aws:ResourceTag/ManagedBy: PingCAP
                Effect: Allow
                Resource:
                  - "*"
                Sid: PushImage
  TiDBCloudAutoDeployRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: auto-deploy-cli
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Sub arn:aws:iam::${ControlPlaneAccountId}:role/auto-deploy-cli
            Action: sts:AssumeRole
          - Effect: Allow
            Principal:
              Federated: "accounts.google.com"
            Action: sts:AssumeRoleWithWebIdentity
            Condition:
              StringEquals:
                accounts.google.com:aud: !Sub ${GithubRunnerGoogleAccountId}
      Policies:
        - PolicyName: auto-deploy-policy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              # Requested by o11y iam
              - Action:
                  - iam:GetRole
                Effect: Allow
                Resource: "*"
                Sid: GetAnyRole
              - Action:
                  - iam:UpdateAssumeRolePolicy
                Effect: Allow
                Resource:
                  - !Sub arn:aws:iam::${AWS::AccountId}:role/tidbcloud-o11y-control-plane-role
                Sid: UpdateO11yControlPlaneRole
              # Requested by o11y eks
              - Action:
                  - iam:CreateOpenIDConnectProvider
                  - iam:DeleteOpenIDConnectProvider
                  - iam:GetOpenIDConnectProvider
                  - iam:ListOpenIDConnectProviders
                  - iam:TagOpenIDConnectProvider
                  - iam:UntagOpenIDConnectProvider
                Effect: Allow
                Resource: "*"
                Sid: CreateOIDCProvider
              # Requested by o11y eks
              - Action:
                  - iam:PassRole
                  - iam:ListAttachedRolePolicies
                Effect: Allow
                Resource:
                  - !Sub arn:aws:iam::${AWS::AccountId}:role/auto-deploy-cli
                  - !Sub arn:aws:iam::${AWS::AccountId}:role/tidbcloud-o11y-eks-node-role
                  - !Sub arn:aws:iam::${AWS::AccountId}:role/tidbcloud-o11y-eks-cluster-role
                  - !Sub arn:aws:iam::${AWS::AccountId}:role/tidbcloud-sli-firehose-role
                Sid: GetDeployRole
              # Requested by o11y eks
              - Action:
                  - iam:CreateServiceLinkedRole
                Effect: Allow
                Resource:
                  - arn:aws:iam::*:role/aws-service-role/eks-nodegroup.amazonaws.com/AWSServiceRoleForAmazonEKSNodegroup
                  - arn:aws:iam::*:role/aws-service-role/eks.amazonaws.com/AWSServiceRoleForAmazonEKS
                Sid: EKSCreateServiceLinkedRole
              - Action:
                  - iam:CreateServiceLinkedRole
                Effect: Allow
                Resource:
                  - arn:aws:iam::*:role/aws-service-role/ops.apigateway.amazonaws.com/AWSServiceRoleForAPIGateway
                Condition:
                  StringEquals:
                    iam:AWSServiceName: ops.apigateway.amazonaws.com
                Sid: ApiGatewayCreateServiceLinkedRole
              # Requested by o11y
              - Action:
                  - elasticloadbalancing:DescribeLoadBalancers
                  - elasticloadbalancing:DescribeLoadBalancerAttributes
                  - elasticloadbalancing:DescribeTags
                Effect: Allow
                Resource: "*"
                Sid: ELBRead
              # Requested by o11y
              - Action:
                  - cloudformation:DescribeStacks
                  - cloudformation:ListStacks
                  - cloudformation:DescribeStackEvents
                  - cloudformation:DescribeStackResource
                  - cloudformation:DescribeStackResources
                  - cloudformation:GetTemplate
                  - cloudformation:ValidateTemplate
                  - cloudformation:GetTemplateSummary
                  - cloudformation:DescribeChangeSet
                  - cloudformation:ListChangeSets
                Effect: Allow
                Resource: "*"
                Sid: CloudFormationReadOnly
              # Requested by o11y
              - Action:
                  - cloudformation:CreateStack
                  - cloudformation:DeleteStack
                  - cloudformation:UpdateStack
                  - cloudformation:TagResource
                  - cloudformation:UntagResource
                  - cloudformation:CreateChangeSet
                  - cloudformation:ExecuteChangeSet
                  - cloudformation:DeleteChangeSet
                Effect: Allow
                Resource: arn:aws:cloudformation:*:*:stack/auto-deploy-o11y-*/*
                Sid: CloudFormationWrite
              # Requested by o11y eks
              - Action:
                  - ec2:RunInstances
                  - ec2:TerminateInstances
                  - ec2:CreateVpc
                  - ec2:DeleteVpc
                  - ec2:ModifyVpcAttribute
                  - ec2:CreateSubnet
                  - ec2:DeleteSubnet
                  - ec2:ModifySubnetAttribute
                  - ec2:CreateSecurityGroup
                  - ec2:DeleteSecurityGroup
                  - ec2:AuthorizeSecurityGroupIngress
                  - ec2:RevokeSecurityGroupIngress
                  - ec2:AuthorizeSecurityGroupEgress
                  - ec2:RevokeSecurityGroupEgress
                  - ec2:CreateRouteTable
                  - ec2:DeleteRouteTable
                  - ec2:AssociateRouteTable
                  - ec2:DisassociateRouteTable
                  - ec2:CreateRoute
                  - ec2:DeleteRoute
                  - ec2:CreateInternetGateway
                  - ec2:DeleteInternetGateway
                  - ec2:AttachInternetGateway
                  - ec2:DetachInternetGateway
                  - ec2:AllocateAddress
                  - ec2:ReleaseAddress
                  - ec2:DisassociateAddress
                  - ec2:CreateNatGateway
                  - ec2:DeleteNatGateway
                  - ec2:CreateLaunchTemplate
                  - ec2:DeleteLaunchTemplate
                  - ec2:CreateLaunchTemplateVersion
                  - ec2:DeleteLaunchTemplateVersions
                  - ec2:ModifyLaunchTemplate
                  - ec2:CreateTags
                  - ec2:DeleteTags
                  - ec2:CreateNetworkAclEntry
                  - ec2:DeleteNetworkAclEntry
                  - ec2:CreateVpcEndpoint
                  - ec2:DeleteVpcEndpoints
                  - ec2:ModifyVpcEndpoint
                  - ec2:CreateVpcEndpointServiceConfiguration
                  - ec2:DeleteVpcEndpointServiceConfigurations
                  - ec2:ModifyVpcEndpointServiceConfiguration
                  - ec2:ModifyVpcEndpointServicePermissions
                Effect: Allow
                Resource: "*"
                Sid: "EC2Write"
              # Requested by o11y eks
              - Action:
                  - ec2:Describe*
                Effect: Allow
                Resource: "*"
                Sid: "EC2ReadOnly"
              # Requested by o11y eks
              - Action:
                  - autoscaling:AttachInstances
                  - autoscaling:DetachInstances
                  - autoscaling:CreateAutoScalingGroup
                  - autoscaling:DeleteAutoScalingGroup
                  - autoscaling:UpdateAutoScalingGroup
                  - autoscaling:TerminateInstanceInAutoScalingGroup
                Effect: Allow
                Resource:
                  - "arn:aws:autoscaling:*:*:autoScalingGroup:*:autoScalingGroupName/eks-worker-*"
                  - "arn:aws:ec2:*:*:instance/*"
                Sid: "ASGWriteWithPrefix"
              # Requested by o11y eks
              - Action:
                  - autoscaling:DescribeAutoScalingGroups
                Effect: Allow
                Resource: "*"
                Sid: "ASGReadOnly"
              # Requested by o11y eks
              - Action:
                  - eks:CreateAddon
                  - eks:DeleteAddon
                  - eks:UpdateAddon
                  - eks:CreateCluster
                  - eks:DeleteCluster
                  - eks:UpdateClusterConfig
                  - eks:UpdateClusterVersion
                  - eks:AssociateIdentityProviderConfig
                  - eks:DisassociateIdentityProviderConfig
                  - eks:CreateNodegroup
                  - eks:DeleteNodegroup
                  - eks:UpdateNodegroupConfig
                  - eks:CreateAccessEntry
                  - eks:DeleteAccessEntry
                  - eks:AssociateAccessPolicy
                  - eks:DisassociateAccessPolicy
                  - eks:TagResource
                  - eks:UntagResource
                Effect: Allow
                Resource:
                  - arn:aws:eks:*:*:cluster/o11y-*
                  - arn:aws:eks:*:*:addon/o11y-*/*/*
                  - arn:aws:eks:*:*:nodegroup/o11y-*/*/*
                  - arn:aws:eks:*:*:access-entry/o11y-*/role/*/*/*
                Sid: "EKSWrite"
              # Requested by o11y eks
              - Action:
                  - eks:Describe*
                  - eks:List*
                Effect: Allow
                Resource: "*"
                Sid: "EKSReadOnly"
              # Requested by o11y, sli
              - Action:
                  - s3:CreateBucket
                  - s3:PutBucketPolicy
                  - s3:PutBucketTagging
                  - s3:PutBucketPublicAccessBlock
                  - s3:PutLifecycleConfiguration
                Effect: Allow
                Resource:
                  - arn:aws:s3:::tidbcloud-*
                  - arn:aws:s3:::o11y-*
                  - arn:aws:s3:::loki-*
                Sid: "S3Write"
              # Requested by o11y, sli
              - Action:
                  - s3:ListBucket
                  - s3:GetBucketTagging
                  - s3:GetBucketPolicy
                  - s3:GetBucketPublicAccessBlock
                  - s3:GetLifecycleConfiguration
                  - s3:GetBucketAcl
                  - s3:GetBucketCORS
                  - s3:GetBucketWebsite
                  - s3:GetBucketVersioning
                  - s3:GetAccelerateConfiguration
                  - s3:GetBucketRequestPayment
                  - s3:GetBucketLogging
                  - s3:GetReplicationConfiguration
                  - s3:GetEncryptionConfiguration
                  - s3:GetBucketObjectLockConfiguration
                Effect: Allow
                Resource: "*"
                Sid: "S3ReadOnly"
              # Requested by o11y
              - Action:
                  - route53:ChangeResourceRecordSets
                Effect: Allow
                Resource:
                  - !Sub arn:aws:route53:::hostedzone/${O11yHostedZoneId}
                Sid: "Route53Write"
              - !If
                - HasAdditionalO11yZones
                - Action:
                    - route53:ChangeResourceRecordSets
                  Effect: Allow
                  Resource: !Ref AdditionalO11yHostedZoneIds
                  Sid: "Route53WriteAdditional"
                - !Ref AWS::NoValue
              - Action:
                  - route53:GetHostedZone
                  - route53:GetChange
                  - route53:ListHostedZones
                  - route53:ListHostedZonesByName
                  - route53:ListResourceRecordSets
                  - route53:ListTagsForResource
                Effect: Allow
                Resource: "*"
                Sid: "Route53ReadOnly"
              # Requested by o11y
              - Action:
                  - cloudwatch:DescribeAlarms
                  - cloudwatch:ListTagsForResource
                Effect: Allow
                Resource:
                  - arn:aws:cloudwatch:*:*:alarm:WatchdogDown-*
                  - arn:aws:cloudwatch:*:*:alarm:AlertmanagerClusterFailedToSendAlerts-*
                Sid: "CloudWatchReadOnly"
              # Requested by o11y
              - Action:
                  - cloudwatch:PutMetricAlarm
                Effect: Allow
                Resource:
                  - arn:aws:cloudwatch:*:*:alarm:WatchdogDown-*
                  - arn:aws:cloudwatch:*:*:alarm:AlertmanagerClusterFailedToSendAlerts-*
                Sid: "CloudWatchWrite"
              # Requested by o11y
              - Action:
                  - acm:RequestCertificate
                  - acm:RevokeCertificate
                  - acm:DeleteCertificate
                  - acm:AddTagsToCertificate
                Effect: Allow
                Resource: "*"
                Sid: "ACMWrite"
              # Requested by o11y
              - Action:
                  - acm:DescribeCertificate
                Effect: Allow
                Resource: "*"
                Sid: "ACMReadOnly"
              # Requested by o11y
              - Action:
                  - wafv2:CreateIPSet
                  - wafv2:DeleteIPSet
                  - wafv2:UpdateIPSet
                  - wafv2:CreateWebACL
                  - wafv2:DeleteWebACL
                  - wafv2:UpdateWebACL
                  - wafv2:AssociateWebACL
                  - wafv2:TagResource
                  - wafv2:UntagResource
                Effect: Allow
                Resource: "*"
                Sid: "WAFWrite"
              # Requested by o11y
              - Action:
                  - wafv2:GetIPSet
                  - wafv2:GetWebACL
                  - wafv2:ListTagsForResource
                Effect: Allow
                Resource: "*"
                Sid: "WAFReadOnly"
              # Requested by sli, o11y
              - Action:
                  - logs:CreateLogGroup
                  - logs:PutRetentionPolicy
                  - logs:CreateLogStream
                  - logs:TagResource
                Effect: Allow
                Resource:
                  - arn:aws:logs:*:*:log-group:/aws/eks/o11y-*/cluster:*
                  - arn:aws:logs:*:*:log-group:/aws/kinesisfirehose/tidbcloud-*:*
                Sid: "losWrite"
              - Action:
                  - logs:ListTagsForResource
                Effect: Allow
                Resource:
                  - arn:aws:logs:*:*:log-group:/aws/eks/o11y-*/cluster
                  - arn:aws:logs:*:*:log-group:/aws/kinesisfirehose/tidbcloud-*
                Sid: "LogsTagReadOnly"
              - Action:
                  - logs:DeleteLogGroup
                Effect: Allow
                Resource:
                  - arn:aws:logs:*:*:log-group:/aws/eks/o11y-*/cluster
                  - arn:aws:logs:*:*:log-group:/aws/kinesisfirehose/tidbcloud-*
                Sid: "LogsDelete"
              - Action:
                  - logs:DeleteLogStream
                Effect: Allow
                Resource:
                  - arn:aws:logs:*:*:log-group:/aws/eks/o11y-*/cluster:log-stream:*
                  - arn:aws:logs:*:*:log-group:/aws/kinesisfirehose/tidbcloud-*:log-stream:*
                Sid: "LogsStreamDelete"
              - Action:
                  - logs:DescribeLogGroups
                  - logs:DescribeLogStreams
                Effect: Allow
                Resource: "*"
                Sid: "LogsReadOnly"
              # Requested by sli
              - Action:
                  - vpce:AllowMultiRegion
                Effect: Allow
                Resource: "*"
              # Requested by sli
              - Action:
                  - glue:CreateDatabase
                  - glue:DeleteDatabase
                  - glue:CreateTable
                  - glue:DeleteTable
                  - glue:GetTable
                  - glue:TagResource
                  - glue:GetDatabase
                  - glue:GetTags
                Effect: Allow
                Resource:
                  - arn:aws:glue:*:*:catalog
                  - arn:aws:glue:*:*:database/tidbcloud-*
                  - arn:aws:glue:*:*:table/tidbcloud-*
                  - arn:aws:glue:*:*:userDefinedFunction/tidbcloud-*/*
              - Action:
                  - apigateway:GET
                  - apigateway:POST
                  - apigateway:PUT
                  - apigateway:DELETE
                  - apigateway:TagResource
                Effect: Allow
                Resource:
                  - arn:aws:apigateway:*::/restapis
                  - arn:aws:apigateway:*::/restapis/*
                  - arn:aws:apigateway:*::/vpclinks
                  - arn:aws:apigateway:*::/vpclinks/*
                  - arn:aws:apigateway:*::/tags/*
                Sid: "ApiGatewayWrite"
              # Requested by sli
              - Action:
                  - firehose:CreateDeliveryStream
                  - firehose:DeleteDeliveryStream
                  - firehose:TagDeliveryStream
                Effect: Allow
                Resource:
                  - arn:aws:firehose:*:*:deliverystream/tidbcloud-*
              # Requested by sli
              - Action:
                  - firehose:ListTagsForDeliveryStream
                  - firehose:DescribeDeliveryStream
                Effect: Allow
                Resource:
                  - arn:aws:firehose:*:*:deliverystream/tidbcloud-*
              - Action:
                  - route53-recovery-control-config:ListControlPanels
                  - route53domains:ListDomains
                  - route53domains:ListOperations
                  - route53-recovery-readiness:ListReadinessChecks
                Effect: Allow
                Resource: "*"
              - Action:
                  - kms:CreateKey
                  - kms:CreateAlias
                  - kms:TagResource
                  - kms:UntagResource
                Effect: Allow
                Resource: "*"
                Sid: "KMSWrite"
              - Action:
                  - kms:DescribeKey
                  - kms:ListKeys
                  - kms:ListAliases
                  - kms:ListResourceTags
                Effect: Allow
                Resource: "*"
                Sid: "KMSReadOnly"
