AWSTemplateFormatVersion: '2010-09-09'
Description: Stack that will deployed across all accounts in an org so we can assume to read data using a lambda 
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
    - Label:
        default: 'Deployment parameters'
      Parameters:
        - CostAccountID
        - MultiAccountRoleName
        - RolePrefix
    - Label:
        default: 'Available modules'
      Parameters:
        - IncludeTAModule
        - IncludeInventoryCollectorModule
        - IncludeECSChargebackModule
        - IncludeRDSUtilizationModule
        - IncludeBudgetsModule
        - IncludeTransitGatewayModule
    ParameterLabels:
      CostAccountID:
        default: 'Cost Account Id'
      MultiAccountRoleName:
        default: 'Multi Account Role Name'
      RolePrefix:
        default: "Role Prefix"
      IncludeTAModule:
        default: 'Include AWS Trusted Advisor Data Collection Module'
      IncludeInventoryCollectorModule:
        default: 'Include Inventory Collector Module'
      IncludeECSChargebackModule:
        default: 'Include ECS Chargeback Data Collection Module'
      IncludeRDSUtilizationModule:
        default: 'Include RDS Utilization Data Collection Module' 
      IncludeBudgetsModule:
        default: 'Include Budgets Collection Module'    
      IncludeTransitGatewayModule:
        default: 'Include Transit Gateway Module'  
Parameters:
  CostAccountID:
    Type: String
    Description: AccountId of where the collector is deployed
  MultiAccountRoleName:
    Type: String
    Description: The name of the IAM role that will be deployed from the management account to linked accounts as a read only role. DO NOT ENTER THE ROLE PREFIX HERE. KEEP THE SAME AS WHAT IS DEPLOYED INTO MANAGEMENT ACCOUNT.
    Default: "Optimization-Data-Multi-Account-Role"
  RolePrefix:
    Type: String
    Description: Keep this consistent with the prefix used for the Stacks and StackSets created as part of this lab. This prefix will be placed in front of all roles created. Note you may wish to add a dash at the end to make more readable e.g. prefix-
    Default: "WA-"
  IncludeTAModule:
    Type: String
    Description: Collects AWS Trusted Advisor recommendations data
    AllowedValues:
      - "yes"
      - "no"  
  IncludeInventoryCollectorModule:
    Type: String
    Description: Collects data about AMIs, EBS volumes and snapshots
    AllowedValues:
      - "yes"
      - "no" 
  IncludeECSChargebackModule:
    Type: String
    Description: Collects data which shows costs associated with ECS Tasks leveraging EC2 instances within a Cluster
    AllowedValues:
      - "yes"
      - "no" 
  IncludeRDSUtilizationModule:
    Type: String
    Description: Collects RDS CloudWatch metrics from your accounts
    AllowedValues:
      - "yes"
      - "no" 
  IncludeBudgetsModule:
    Type: String
    Description: Collects budgets from your accounts
    AllowedValues:
      - "yes"
      - "no"
  IncludeTransitGatewayModule:
    Type: String
    Description: Collects TransitGateway from your accounts
    AllowedValues:
      - "yes"
      - "no"    

Conditions:
  IncludeTAModulePolicy: !Equals 
    - !Ref IncludeTAModule
    - "yes"
  IncludeInventoryCollectorModulePolicy: !Equals 
    - !Ref IncludeInventoryCollectorModule
    - "yes"
  IncludeECSChargebackModulePolicy: !Equals 
    - !Ref IncludeECSChargebackModule
    - "yes"
  IncludeRDSUtilizationModulePolicy: !Equals
    - !Ref IncludeRDSUtilizationModule
    - "yes"  
  IncludeBudgetsModulePolicy: !Equals
    - !Ref IncludeBudgetsModule
    - "yes"
  IncludeTransitGatewayModulePolicy: !Equals
    - !Ref IncludeTransitGatewayModule
    - "yes"

Outputs:
  LambdaRole:
    Description: For lambda to assume in cost account 
    Value:
      Fn::GetAtt:
        - LambdaRole
        - Arn 
Resources:
  LambdaRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${RolePrefix}${MultiAccountRoleName}"
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              AWS:
                -  !Sub "arn:aws:iam::${CostAccountID}:root"
        Version: 2012-10-17
      Path: /
  AMIPolicy:
    Type: 'AWS::IAM::Policy'
    Properties:
      PolicyName: ami
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action:
              - "imagebuilder:ListImages"
              - "imagebuilder:GetImage"
            Resource: "*" ## only * can be used as a Resource for this action
      Roles:
        - Ref: LambdaRole
  TAPolicy:
    Type: 'AWS::IAM::Policy'
    Condition: IncludeTAModulePolicy
    Properties:
      PolicyName: TAPolicy
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action:
              - "trustedadvisor:Describe*"
              - "trustedadvisor:List*"
              - "trustedadvisor:GenerateReport"
              - "trustedadvisor:IncludeCheckItems"
              - "trustedadvisor:ExcludeCheckItems"
              - "trustedadvisor:RefreshCheck"                   
              - "support:DescribeTrustedAdvisorChecks"
              - "support:DescribeTrustedAdvisorCheckResult"
            Resource: "*" ## only * can be used as a Resource for this action
      Roles:
        - Ref: LambdaRole
  BudgetsReadOnlyPolicy:
    Type: 'AWS::IAM::Policy'
    Condition: IncludeBudgetsModulePolicy
    Properties:
      PolicyName: BudgetsReadOnlyPolicy
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action:
              - "budgets:ViewBudget"
              - "budgets:Describe*"
            Resource: "arn:aws:budgets::*:budget/*" ## only * can be used as a Resource for this action
      Roles:
        - Ref: LambdaRole
  InventoryCollectorPolicy:
    Type: 'AWS::IAM::Policy'
    Condition: IncludeInventoryCollectorModulePolicy
    Properties:
      PolicyName: InventoryCollectorPolicy
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action:
              - "ec2:DescribeImages"
              - "ec2:DescribeVolumeStatus"
              - "ec2:DescribeVolumes"
              - "ec2:DescribeSnapshots"
              - "ec2:DescribeSnapshotAttribute"
            Resource: "*" ## only * can be used for inventory
      Roles:
        - Ref: LambdaRole
  ECSChargebackPolicy:
    Type: 'AWS::IAM::Policy'
    Condition: IncludeECSChargebackModulePolicy
    Properties:
      PolicyName: ECSChargebackPolicy
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action:
              - "ecs:ListAttributes"
              - "ecs:DescribeTaskSets"
              - "ecs:DescribeTaskDefinition"
              - "ecs:DescribeClusters"
              - "ecs:ListServices"
              - "ecs:ListAccountSettings"
              - "ecs:DescribeCapacityProviders"
              - "ecs:ListTagsForResource"
              - "ecs:ListTasks"
              - "ecs:ListTaskDefinitionFamilies"
              - "ecs:DescribeServices"
              - "ecs:ListContainerInstances"
              - "ecs:DescribeContainerInstances"
              - "ecs:DescribeTasks"
              - "ecs:ListTaskDefinitions"
              - "ecs:ListClusters"
            Resource: "*" ## only * can be used for inventory
      Roles:
        - Ref: LambdaRole 
  RDSUtilizationPolicy:
    Type: 'AWS::IAM::Policy'
    Condition: IncludeRDSUtilizationModulePolicy
    Properties:
      PolicyName: RDSUtilizationPolicy
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action:
              - "rds:DescribeDBProxyTargetGroups"
              - "rds:DescribeDBInstanceAutomatedBackups"
              - "rds:DescribeDBEngineVersions"
              - "rds:DescribeDBSubnetGroups"
              - "rds:DescribeGlobalClusters"
              - "rds:DescribeExportTasks"
              - "rds:DescribePendingMaintenanceActions"
              - "rds:DescribeEngineDefaultParameters"
              - "rds:DescribeDBParameterGroups"
              - "rds:DescribeDBClusterBacktracks"
              - "rds:DescribeCustomAvailabilityZones"
              - "rds:DescribeReservedDBInstancesOfferings"
              - "rds:DescribeDBProxyTargets"
              - "rds:DownloadDBLogFilePortion"
              - "rds:DescribeDBInstances"
              - "rds:DescribeSourceRegions"
              - "rds:DescribeEngineDefaultClusterParameters"
              - "rds:DescribeInstallationMedia"
              - "rds:DescribeDBProxies"
              - "rds:DescribeDBParameters"
              - "rds:DescribeEventCategories"
              - "rds:DescribeDBProxyEndpoints"
              - "rds:DescribeEvents"
              - "rds:DescribeDBClusterSnapshotAttributes"
              - "rds:DescribeDBClusterParameters"
              - "rds:DescribeEventSubscriptions"
              - "rds:DescribeDBSnapshots"
              - "rds:DescribeDBLogFiles"
              - "rds:DescribeDBSecurityGroups"
              - "rds:DescribeDBSnapshotAttributes"
              - "rds:DescribeReservedDBInstances"
              - "rds:ListTagsForResource"
              - "rds:DescribeValidDBInstanceModifications"
              - "rds:DescribeDBClusterSnapshots"
              - "rds:DescribeOrderableDBInstanceOptions"
              - "rds:DescribeOptionGroupOptions"
              - "rds:DescribeDBClusterEndpoints"
              - "rds:DescribeCertificates"
              - "rds:DescribeDBClusters"
              - "rds:DescribeAccountAttributes"
              - "rds:DescribeOptionGroups"
              - "rds:DescribeDBClusterParameterGroups"
            Resource: "*"
          - Effect: "Allow" ## only * can be used for inventory
            Action:
              - "ec2:DescribeRegions"
              - "cloudwatch:GetMetricStatistics"
            Resource: "*" ## only * can be used as a Resource for this action
      Roles:
        - Ref: LambdaRole
  TransitGatewayPolicy:
    Type: 'AWS::IAM::Policy'
    Condition: IncludeTransitGatewayModulePolicy
    Properties:
      PolicyName: TransitGatewayPolicy
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action:
              - "ec2:DescribeTransitGatewayAttachments"
              - "cloudwatch:Describe*"
              - "cloudwatch:Get*"
              - "cloudwatch:List*"
            Resource: "*" ## only * can be used for inventory
      Roles:
        - Ref: LambdaRole 
