---
# =============================================================================
# ZapStack Member Account Template (v1-member)
# =============================================================================
#
# DO NOT DEPLOY THIS TEMPLATE MANUALLY!
#
# This template is automatically deployed to ALL member accounts in your
# AWS Organization via a StackSet created by v1.yaml in the management account.
#
# WHAT THIS TEMPLATE CREATES:
#   1. IAM role for ZapStack to assume (cross-account access)
#   2. Notification to ZapStack backend when the member account is onboarded
#
# HOW IT GETS DEPLOYED:
#   - The management account's v1.yaml creates a StackSet
#   - The StackSet auto-deploys this template to all existing member accounts
#   - New accounts added to the Organization automatically get this template
#   - Removed accounts automatically have this stack deleted
#
# PERMISSIONS:
#   This role has READ-ONLY access for resource inventory and metrics.
#   It does NOT have access to:
#     - Cost and Usage Reports (only management account has CUR)
#     - Billing APIs (billing is centralized in management account)
#     - StackSet management (only management account manages StackSets)
#
# =============================================================================
AWSTemplateFormatVersion: "2010-09-09"
Description: ZapStack cross-account IAM role for member accounts

# =============================================================================
# PARAMETERS
# These values are passed from the StackSet in v1.yaml.
# Do not modify them - they must match the management account configuration.
# =============================================================================
Parameters:
  ZapStackID:
    Type: String
    Description: ZapStack tenant ID
  ZapStackAccount:
    Type: String
    Description: ZapStack AWS account ID
  ZapStackSnsTopicArn:
    Type: String
    Description: ZapStack SNS topic ARN for notifications
  Version:
    Type: String
    Description: Template version

Resources:
  # ===========================================================================
  # MEMBER ACCOUNT IAM ROLE
  # ===========================================================================
  # This role allows ZapStack to inventory resources and read CloudWatch metrics
  # in this member account. It's assumed cross-account using STS with ExternalId.
  #
  # The role has read-only access to:
  #   - Resource inventory across all services (via ViewOnlyAccess + extended)
  #   - CloudWatch metrics (for resource utilization analysis)
  #   - S3 multipart upload lists (for detecting abandoned uploads)
  #
  # The role does NOT have:
  #   - Billing/Cost Explorer access (management account only)
  #   - CUR bucket access (management account only)
  #   - StackSet management (management account only)
  # ===========================================================================
  CrossAccountRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: ZapStackCrossAccountRole
      # Trust policy: Only ZapStack's account can assume this role
      # ExternalId prevents confused deputy attacks
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Sub "arn:aws:iam::${ZapStackAccount}:root"
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                # ExternalId must match - prevents other ZapStack customers
                # from accidentally accessing your account
                sts:ExternalId: !Ref ZapStackID
      # AWS managed policy for broad read-only access
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
      Path: "/"
      Policies:
        # ------------------------------------
        # Billing & Cost Data (Limited)
        # ------------------------------------
        # Member accounts can still query their own cost data via Cost Explorer.
        # Note: CUR access is NOT included here (management account only).
        - PolicyName: BillingData
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Sid: ZapStackBillingReadOnly
                Effect: Allow
                Resource: "*"
                Action:
                  - account:GetAccountInformation
                  - budgets:Describe*
                  - budgets:View*
                  - ce:Get*
                  - ce:Describe*
                  - ce:List*
                  - cur:Describe*
                  - invoicing:List*
                  - invoicing:GetInvoice*
                  - pricing:*
                  - organizations:Describe*
                  - organizations:List*
                  - savingsplans:Describe*
                  # Simulate policies to check effective permissions
                  - iam:SimulatePrincipalPolicy

        # ------------------------------------
        # CloudWatch Metrics
        # ------------------------------------
        # Read CloudWatch metrics to analyze resource utilization
        # (e.g., EC2 CPU usage, RDS connections, Lambda invocations)
        - PolicyName: QueryMetrics
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Sid: QueryMetrics
                Effect: Allow
                Resource: "*"
                Action:
                  - cloudwatch:GetMetric*
                  - cloudwatch:ListMetrics

        # ------------------------------------
        # S3 Multipart Upload Detection
        # ------------------------------------
        # Detect incomplete/abandoned multipart uploads
        # (common source of hidden S3 costs)
        - PolicyName: S3ListMultipartUploads
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Sid: MultipartUploads
                Effect: Allow
                Resource: "*"
                Action:
                  - s3:ListBucketMultipartUploads
                  - s3:ListParts

        # ------------------------------------
        # Extended Resource Inventory
        # ------------------------------------
        # ViewOnlyAccess doesn't cover all services. This policy adds
        # read access for additional services needed for complete
        # resource inventory and cost attribution.
        - PolicyName: ZapStackAdditionalResourceReadOnly
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Resource: "*"
                Action:
                  # Certificate Manager
                  - acm:Describe*
                  - acm:List*
                  - acm-pca:Describe*
                  - acm-pca:List*
                  # Amplify
                  - amplify:List*
                  # Auto Scaling
                  - application-autoscaling:Describe*
                  - applicationinsights:Describe*
                  - applicationinsights:List*
                  # AppStream
                  - appstream:Describe*
                  - appstream:List*
                  # AppSync & App Runner
                  - appsync:List*
                  - apprunner:List*
                  - apprunner:Describe*
                  - autoscaling-plans:Describe*
                  # Batch
                  - batch:Describe*
                  # Budgets (redundant with BillingData but explicit)
                  - budgets:Describe*
                  # Cost Explorer
                  - ce:Get*
                  # CloudHSM
                  - cloudhsm:List*
                  - cloudhsm:Describe*
                  # CloudSearch
                  - cloudsearch:Describe*
                  # CloudTrail
                  - cloudtrail:Describe*
                  - cloudtrail:Get*
                  - cloudtrail:List*
                  # CloudWatch
                  - cloudwatch:Describe*
                  # CloudFront
                  - cloudfront:Get*
                  # CodeBuild & CodePipeline
                  - codebuild:Describe*
                  - codebuild:Get*
                  - codebuild:List*
                  - codepipeline:List*
                  - codepipeline:Get*
                  - codestar:Describe*
                  # Connect
                  - connect:Describe*
                  # Data Exchange & DataSync
                  - dataexchange:List*
                  - datasync:Describe*
                  - datasync:List*
                  - datapipeline:Describe*
                  - datapipeline:List*
                  # Detective
                  - detective:List*
                  # Discovery & DMS
                  - discovery:Describe*
                  - dms:Describe*
                  # Directory Service
                  - ds:Describe*
                  - ds:List*
                  # EC2 extended
                  - ec2:Get*
                  - ec2:Search*
                  # ECR & EKS
                  - ecr:Describe*
                  - ecr:List*
                  - eks:Describe*
                  - eks:List*
                  # ElastiCache
                  - elasticache:List*
                  # Elastic Beanstalk
                  - elasticbeanstalk:Describe*
                  - elasticbeanstalk:List*
                  # EFS
                  - elasticfilesystem:Describe*
                  # EMR
                  - elasticmapreduce:Describe*
                  # Elemental
                  - elemental-appliances-software:List*
                  # Elasticsearch/OpenSearch
                  - es:Describe*
                  - es:List*
                  # EventBridge
                  - events:Describe*
                  - events:List*
                  # Kinesis Firehose
                  - firehose:Describe*
                  # FSx
                  - fsx:Describe*
                  - fsx:List*
                  # Glacier
                  - glacier:Describe*
                  # Global Accelerator
                  - globalaccelerator:Describe*
                  - globalaccelerator:List*
                  # Glue
                  - glue:List*
                  # GuardDuty
                  - guardduty:List*
                  # Health
                  - health:Describe*
                  # Image Builder
                  - imagebuilder:List*
                  # Import/Export
                  - importexport:List*
                  # Inspector
                  - inspector:Describe*
                  # IoT
                  - iot:Describe*
                  - iotanalytics:Describe*
                  - iotanalytics:List*
                  - iotsitewise:Describe*
                  - iotsitewise:List*
                  # MSK (Kafka)
                  - kafka:Describe*
                  - kafka:List*
                  # Kinesis
                  - kinesisanalytics:Describe*
                  - kinesisanalytics:List*
                  - kinesisvideo:Describe*
                  - kinesisvideo:List*
                  - kinesis:Describe*
                  - kinesis:List*
                  # KMS
                  - kms:Describe*
                  - kms:List*
                  # License Manager
                  - license-manager:List*
                  # CloudWatch Logs
                  - logs:List*
                  # Media Services
                  - mediaconvert:Describe*
                  - mediaconvert:List*
                  - mediapackage:List*
                  - mediapackage:Describe*
                  - medialive:List*
                  - medialive:Describe*
                  - mediaconnect:List*
                  - mediaconnect:Describe*
                  - mediapackage-vod:List*
                  - mediapackage-vod:Describe*
                  - mediastore:List*
                  - mediastore:Describe*
                  - mediatailor:List*
                  - mediatailor:Describe*
                  # Migration Hub
                  - mgh:Describe*
                  - mgh:List*
                  # Mobile Hub
                  - mobilehub:Describe*
                  - mobilehub:List*
                  - mobiletargeting:List*
                  # MQ
                  - mq:Describe*
                  - mq:List*
                  # OpsWorks
                  - opsworks-cm:List*
                  # Organizations
                  - organizations:Describe*
                  # Outposts
                  - outposts:List*
                  # Personalize
                  - personalize:Describe*
                  - personalize:List*
                  # Performance Insights
                  - pi:Describe*
                  # QLDB
                  - qldb:List*
                  # QuickSight
                  - quicksight:Describe*
                  - quicksight:List*
                  # Resource Access Manager
                  - ram:List*
                  # Rekognition
                  - rekognition:List*
                  # RDS
                  - rds:List*
                  # Redshift
                  - redshift:Describe*
                  # Resource Groups
                  - resource-groups:Get*
                  - resource-groups:List*
                  - resource-groups:Search*
                  # RoboMaker
                  - robomaker:Describe*
                  - robomaker:List*
                  # Route 53 Domains
                  - route53domains:Get*
                  # S3 Lifecycle
                  - s3:GetLifecycleConfiguration
                  # EventBridge Schemas
                  - schemas:Describe*
                  - schemas:List*
                  # Secrets Manager
                  - secretsmanager:List*
                  - secretsmanager:Describe*
                  # Security Hub
                  - securityhub:Describe*
                  - securityhub:List*
                  # Serverless Repo
                  - serverlessrepo:List*
                  # Service Catalog
                  - servicecatalog:Describe*
                  # Cloud Map
                  - servicediscovery:Get*
                  - servicediscovery:List*
                  # SES
                  - ses:Describe*
                  # Shield
                  - shield:Describe*
                  # Snowball
                  - snowball:Describe*
                  - snowball:List*
                  # SQS
                  - sqs:List*
                  # Systems Manager
                  - ssm:Describe*
                  - ssm:List*
                  # IAM Identity Center (SSO)
                  - sso:Describe*
                  - sso:List*
                  - sso:Search*
                  - sso-directory:Describe*
                  - sso-directory:List*
                  - sso-directory:Search*
                  # Step Functions
                  - states:List*
                  - states:Describe*
                  # Storage Gateway
                  - storagegateway:Describe*
                  - storagegateway:List*
                  # SWF
                  - swf:Describe*
                  # Synthetics (CloudWatch)
                  - synthetics:Describe*
                  - synthetics:List*
                  # Resource Tags
                  - tag:Get*
                  # Transfer Family
                  - transfer:Describe*
                  - transfer:List*
                  # Transcribe
                  - transcribe:List*
                  # WAF v2
                  - wafv2:Describe*
                  # WorkLink
                  - worklink:Describe*
                  - worklink:List*
                  # Resource Explorer
                  - resource-explorer-2:Search
                  - resource-explorer-2:List*

  # ===========================================================================
  # ZAPSTACK NOTIFICATION
  # ===========================================================================
  # Sends a message to ZapStack's SNS topic when this member account stack
  # is created or updated. This triggers ZapStack to:
  #   1. Record the member account details
  #   2. Associate it with the parent Organization
  #   3. Begin resource scanning for this account
  #
  # The SNS topic is configured as a CloudFormation custom resource handler,
  # so it responds with success/failure to CloudFormation.
  # ===========================================================================
  ZapStackNotifier:
    Type: AWS::CloudFormation::CustomResource
    Properties:
      ServiceToken: !Ref ZapStackSnsTopicArn
      # Data sent to ZapStack
      AccountID: !Ref AWS::AccountId
      ZapStackID: !Ref ZapStackID
      RoleARN: !GetAtt CrossAccountRole.Arn
      Version: !Ref Version
      StackRegion: !Ref AWS::Region
    UpdateReplacePolicy: Delete

# =============================================================================
# OUTPUTS
# Values exported for reference and debugging
# =============================================================================
Outputs:
  RoleArn:
    Value: !GetAtt CrossAccountRole.Arn
    Description: Cross-account IAM role ARN
  AccountId:
    Value: !Ref AWS::AccountId
    Description: AWS Account ID
