AWSTemplateFormatVersion: 2010-09-09
Description: Connects Cloudwhistle in order to monitor your account's cost in real-time.

Parameters:
  CloudwhistleID:
    Type: String
    Description: ID to link your AWS account. Keep this confidential.
    MinLength: 1
  CloudwhistleSecret:
    Type: String
    Description: Secret to verify access from Cloudwhistle. Keep this confidential.
    MinLength: 1

Resources:
  # This role connects your AWS account with Cloudwhistle.
  # Check out the policies to see what permissions it requires.
  BridgeRole:
    Type: AWS::IAM::Role
    Description: Role that connects this account with Cloudwhistle.
    Properties:
      # (1) This document states that Cloudwhistle will be able to assume this role.
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: arn:aws:iam::339280581914:role/CloudwhistleBridge
            Action:
              - sts:AssumeRole
            Condition:
              StringEquals:
                "sts:ExternalID": !Ref CloudwhistleSecret
      # (2) This managed AWS policy states that Cloudwhistle vill have view-only access
      # to a number of common AWS services. This is needed to create an inventory of
      # resources and their cost dimensiosn (such as EC2's instance-type)
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
      Policies:
        # (3) This policy allows Cloudwhistle to manage a Resource Explorer index and view.
        # The index ensures that resources are found quickly and efficiently across regions.
        - PolicyName: CloudwhistleResourceExplorerPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - resource-explorer-2:CreateIndex
                  - resource-explorer-2:ListIndexes
                Resource: "*"
                Sid: CloudwhistleResourceExplorerIndex
              - Effect: Allow
                Action:
                  - resource-explorer-2:CreateView
                  - resource-explorer-2:ListViews
                  - resource-explorer-2:Search
                Resource: "*"
                Sid: CloudwhistleResourceExplorerView
        # (4) This policy is required by the `resource-explorer-2` service (as indicated by the "Condition").
        # Cloudwhistle will not and can not use this policy itself.
        - PolicyName: CloudwhistleResourceExplorerIAMPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - iam:CreateServiceLinkedRole
                Resource: "*"
                Condition:
                  StringEquals:
                    "iam:AWSServiceName": resource-explorer-2.amazonaws.com
        # (5) This policy extends AWS' view-only permissions to get access to more services.
        # This extends the scope of resources Cloudwhistle can track the cost for.
        - PolicyName: CloudwhistleExtendedViewOnlyAccess
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - aws-portal:View* # list active regions
                  - budgets:Describe* # describe Budget
                  - budgets:View* # list Budgets
                  - ce:Get* # get Cost Explorer preferences
                  - ce:Describe* # describe Cost Explorer reports/cost categories
                  - ce:List* # list Cost Explorer cost categories
                  - cur:Describe* # describe Cost and Usage reports
                  - elasticache:List* # list ElasticCache resources
                  - es:Describe* # describe ElasticSearch resource
                  - es:List* # list ElasticSearch resources
                  - lambda:GetFunctionConfiguration # get Lambda configuration
                  - organizations:Describe* # describe Organizations
                  - organizations:List* # list Organizations
                  - pricing:* # query resource prices
                  - rds:List* # list RDS resources
                  - savingsplans:Describe* # describe Savings Plan
                  - support:Get* # get Support Plan details
                Resource: "*"

  # The callback sends a message (with the listed properties) to Cloudwhistle.
  # This way it receives the ARN of the new role automatically.
  Callback:
    Type: Custom::CloudwhistleCallbackResource
    Properties:
      ServiceToken: arn:aws:sns:us-east-1:339280581914:CloudwhistleBridge
      BridgeRoleArn: !GetAtt BridgeRole.Arn
      CloudwhistleID: !Ref CloudwhistleID
      Version: 1.0.0

Outputs:
  BridgeRoleArn:
    Value: !GetAtt BridgeRole.Arn
    Description: The ARN of the role to connect with Cloudwhistle.
  Version:
    Value: 1.0.0
    Description: The version of this stack.
