AWSTemplateFormatVersion: '2010-09-09'
Description: >
  Cloud Watchdog circuit-breaker IAM role.
  Grants Cloud Watchdog the read-only permissions PLUS three scoped write
  actions (Lambda throttle, EC2 stop, ECS desired-count). All write actions
  are restricted by IAM Conditions to resources tagged
  `cloudwatchdog:auto-stop=true` AND `env` in (dev, staging).
  Source: https://github.com/cloud-watchdog/iam-templates (version v1.0.0)

Parameters:
  ExternalId:
    Type: String
    Description: Per-account secret issued by Cloud Watchdog. Do not change.
    NoEcho: true
    MinLength: 16
    AllowedPattern: '^[a-zA-Z0-9._:/-]+$'
  CloudWatchdogPrincipalArn:
    Type: String
    Description: ARN of the Cloud Watchdog backend principal that will assume this role.
    AllowedPattern: '^arn:aws:iam::\d{12}:(user|role)/.+$'

Resources:
  CloudWatchdogCircuitBreakerRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub 'CloudWatchdogCircuitBreaker-${AWS::StackName}'
      Description: Read + scoped write access for Cloud Watchdog circuit breakers.
      MaxSessionDuration: 3600
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Ref CloudWatchdogPrincipalArn
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                'sts:ExternalId': !Ref ExternalId
      Policies:
        - PolicyName: CloudWatchdogReadOnlyPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Sid: CostExplorer
                Effect: Allow
                Action:
                  - ce:GetCostAndUsage
                  - ce:GetCostForecast
                  - ce:GetDimensionValues
                Resource: '*'
              - Sid: CloudWatchMetrics
                Effect: Allow
                Action:
                  - cloudwatch:GetMetricStatistics
                  - cloudwatch:GetMetricData
                  - cloudwatch:ListMetrics
                Resource: '*'
              - Sid: TagDiscovery
                Effect: Allow
                Action:
                  - tag:GetResources
                Resource: '*'
              - Sid: ComputeReads
                Effect: Allow
                Action:
                  - ec2:Describe*
                  - lambda:ListFunctions
                  - lambda:GetFunction
                  - lambda:GetFunctionConcurrency
                  - lambda:ListTags
                  - ecs:ListClusters
                  - ecs:ListServices
                  - ecs:DescribeServices
                  - ecs:DescribeClusters
                  - ecs:ListTagsForResource
                Resource: '*'
              - Sid: DataServiceReads
                Effect: Allow
                Action:
                  - rds:DescribeDBInstances
                  - rds:ListTagsForResource
                Resource: '*'
              - Sid: NetworkReads
                Effect: Allow
                Action:
                  - elasticloadbalancing:Describe*
                Resource: '*'
              - Sid: LogsReads
                Effect: Allow
                Action:
                  - logs:DescribeLogGroups
                  - logs:ListTagsForResource
                Resource: '*'
        - PolicyName: CloudWatchdogScopedWritePolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Sid: Ec2StopOnTaggedDevOnly
                Effect: Allow
                Action:
                  - ec2:StopInstances
                  - ec2:StartInstances
                Resource: '*'
                Condition:
                  StringEquals:
                    'aws:ResourceTag/cloudwatchdog:auto-stop': 'true'
                  StringEqualsIgnoreCase:
                    'aws:ResourceTag/env':
                      - dev
                      - staging
              - Sid: LambdaThrottleOnTaggedDevOnly
                Effect: Allow
                Action:
                  - lambda:PutFunctionConcurrency
                  - lambda:DeleteFunctionConcurrency
                Resource: '*'
                Condition:
                  StringEquals:
                    'aws:ResourceTag/cloudwatchdog:auto-stop': 'true'
                  StringEqualsIgnoreCase:
                    'aws:ResourceTag/env':
                      - dev
                      - staging
              - Sid: EcsScaleOnTaggedDevOnly
                Effect: Allow
                Action:
                  - ecs:UpdateService
                Resource: '*'
                Condition:
                  StringEquals:
                    'aws:ResourceTag/cloudwatchdog:auto-stop': 'true'
                  StringEqualsIgnoreCase:
                    'aws:ResourceTag/env':
                      - dev
                      - staging

Outputs:
  RoleArn:
    Description: Paste this Role ARN into Cloud Watchdog to complete the connection.
    Value: !GetAtt CloudWatchdogCircuitBreakerRole.Arn
  ExternalId:
    Description: External ID used in the trust policy (echoed for your records).
    Value: !Ref ExternalId
  PermissionMode:
    Description: This stack grants read + scoped write access on dev/staging only.
    Value: CIRCUIT_BREAKER
