AWSTemplateFormatVersion: "2010-09-09"
Description: SpendPilot read-only IAM role for Cost Explorer and inventory describe APIs.

Parameters:
  ExternalId:
    Type: String
    Description: External ID SpendPilot provides when assuming this role
    MinLength: 8
  SpendPilotPrincipalArn:
    Type: String
    Description: IAM user/role ARN in the SpendPilot AWS account that will assume this role
    Default: arn:aws:iam::ACCOUNT_ID:root

Resources:
  SpendPilotReadOnlyRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: SpendPilotReadOnly
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Ref SpendPilotPrincipalArn
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                sts:ExternalId: !Ref ExternalId
      Policies:
        - PolicyName: SpendPilotCostAndInventoryRead
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Sid: CostExplorerRead
                Effect: Allow
                Action:
                  - ce:GetCostAndUsage
                  - ce:GetCostForecast
                  - ce:GetDimensionValues
                  - ce:GetTags
                  - ce:GetAnomalies
                  - ce:GetAnomalyMonitors
                  - ce:GetReservationCoverage
                  - ce:GetSavingsPlansCoverage
                  - ce:GetSavingsPlansUtilization
                Resource: "*"
              - Sid: BillingRead
                Effect: Allow
                Action:
                  - budgets:ViewBudget
                  - billing:GetBillingData
                  - billing:GetBillingDetails
                  - cur:DescribeReportDefinitions
                Resource: "*"
              - Sid: InventoryDescribe
                Effect: Allow
                Action:
                  - ec2:Describe*
                  - elasticloadbalancing:Describe*
                  - rds:Describe*
                  - rds:ListTagsForResource
                  - elasticache:Describe*
                  - elasticache:ListTagsForResource
                  - es:Describe*
                  - es:ListDomainNames
                  - es:ListTags
                  - kafka:ListClusters
                  - kafka:ListClustersV2
                  - kafka:Describe*
                  - kafka:ListTagsForResource
                  - eks:ListClusters
                  - eks:DescribeCluster
                  - eks:ListNodegroups
                  - eks:DescribeNodegroup
                  - autoscaling:Describe*
                  - apigateway:GET
                  - cloudwatch:GetMetricData
                  - cloudwatch:GetMetricStatistics
                  - cloudwatch:ListMetrics
                  - tag:GetResources
                  - organizations:DescribeAccount
                  - compute-optimizer:Get*
                  - compute-optimizer:Describe*
                  - s3:ListAllMyBuckets
                  - s3:ListBucket
                  - s3:ListBucketMultipartUploads
                  - s3:GetBucketLocation
                Resource: "*"
              - Sid: DenyWrites
                Effect: Deny
                Action:
                  - ec2:TerminateInstances
                  - ec2:Delete*
                  - rds:Delete*
                  - rds:Modify*
                  - elasticloadbalancing:Delete*
                  - s3:DeleteObject
                  - s3:AbortMultipartUpload
                  - eks:Delete*
                  - kafka:Delete*
                  - es:Delete*
                  - iam:Create*
                  - iam:Delete*
                  - iam:Put*
                Resource: "*"

Outputs:
  RoleArn:
    Description: Paste this Role ARN into SpendPilot
    Value: !GetAtt SpendPilotReadOnlyRole.Arn
  ExternalIdOut:
    Description: External ID used in the trust policy
    Value: !Ref ExternalId
