AWSTemplateFormatVersion: '2010-09-09'
Description: WorkSpaces SSM - Configure AWS Systems Manager with default roles, baseline and maintenance windows 
Parameters :
  ExistingManagedInstanceProfile : 
    Type : 'String'
    Description : "(Optional) The name of the IAM Instance Profile that grants permissions to AWS Systems Manager."
    Default: ''
Conditions:
  CreateManagedInstanceProfileCondition:
    Fn::Equals:
    - Ref: ExistingManagedInstanceProfile
    - ''    
Resources:
  RoleSSMMaintenance:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          Effect: Allow
          Principal:
            Service:
            - ssm.amazonaws.com
          Action: sts:AssumeRole
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AmazonSSMMaintenanceWindowRole
      RoleName:
        Fn::Join:
        - ''
        - - Ref: AWS::Region
          - "-"
          - roles_ssm_maintenance
  RoleSSMInstance:
    Type: AWS::IAM::Role
    Condition: CreateManagedInstanceProfileCondition
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          Effect: Allow
          Principal:
            Service: ssm.amazonaws.com
          Action: sts:AssumeRole
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
      Policies:
      - PolicyName: WorkSpacesSSM-S3Permissions
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - s3:GetObject
            - s3:PutObject
            - s3:PutObjectAcl
            Resource: 
              - !Join [ '', ['arn:aws:s3:::', Fn::ImportValue: WorkSpacesSSMInventoryBucket ] ]
              - !Join [ '', ['arn:aws:s3:::', Fn::ImportValue: WorkSpacesSSMInventoryBucket, '/*'] ]      
      RoleName:
        Fn::Join:
        - ''
        - - Ref: AWS::Region
          - "-"
          - role_ssm_manageinstances          
  RoleSSMInstanceProf:
    Type: AWS::IAM::InstanceProfile
    Condition: CreateManagedInstanceProfileCondition
    Properties:
      Path: "/"
      Roles:
      - Ref: RoleSSMInstance
      InstanceProfileName:
        Fn::Join:
        - ''
        - - Ref: AWS::Region
          - "-"
          - instanceprofile_ssm
  S3ResourceSync:
    Type: AWS::SSM::ResourceDataSync
    Properties:
      BucketName:
        Fn::Join:
        - "-"
        - - s3
          - Ref: AWS::AccountId
          - ssm-inventory-bucket
      BucketRegion: !Ref AWS::Region
      SyncFormat: JsonSerDe
      SyncName: WorkSpaces-SSM-DataSync
  WindowsWorkSpacesAllBaseline:
    Type: AWS::SSM::PatchBaseline
    Properties:
      OperatingSystem: WINDOWS
      PatchGroups:
      - WinWorkSpacesGroup1
      - WinWorkSpacesGroup2
      Description: Patch Baseline for ALL Windows operating systems
      ApprovalRules:
        PatchRules:
        - ApproveAfterDays: 5
          PatchFilterGroup:
            PatchFilters:
            - Key: PRODUCT
              Values:
              - "*"
            - Key: CLASSIFICATION
              Values:
              - CriticalUpdates
              - SecurityUpdates
            - Key: MSRC_SEVERITY
              Values:
              - Critical
              - Important
      Name: WorkSpaces-Windows-All-Baseline
  AMZLINWorkSpacesAllBaseline:
    Type: AWS::SSM::PatchBaseline
    Properties:
      OperatingSystem: AMAZON_LINUX_2
      PatchGroups:
      - AMZLINWorkSpacesGroup1
      - AMZLINWorkSpacesGroup2
      Description: Patch Baseline for ALL Amazon Linux operating systems
      ApprovalRules:
        PatchRules:
        - ApproveAfterDays: 5
          PatchFilterGroup:
            PatchFilters:
            - Key: PRODUCT
              Values:
              - "*"
            - Key: CLASSIFICATION
              Values:
              - Security
            - Key: SEVERITY
              Values:
              - Critical
              - Important
      Name: WorkSpacwes-AmazonLinux-All-Baseline
  WKSMaintWindowA:
    Type: AWS::SSM::MaintenanceWindow
    Properties:
      Description: WorkSpaces Maintenance Window A - Sunday 00:00 - 04:00
      AllowUnassociatedTargets: 'False'
      Cutoff: 1
      Schedule: cron(0 0 ? * SUN *)
      Duration: 4
      Name: WorkSpacesMaintenanceWindowA
  WKSMaintWindowB:
    Type: AWS::SSM::MaintenanceWindow
    Properties:
      Description: WorkSpaces Maintenance Window B - Monday 00:00 - 04:00
      AllowUnassociatedTargets: 'False'
      Cutoff: 1
      Schedule: cron(0 0 ? * MON *)
      Duration: 4
      Name: WorkSpacesMaintenanceWindowB
  WKSMaintWindowTargetA:
    Type: AWS::SSM::MaintenanceWindowTarget
    Properties:
      OwnerInformation: Amazon WorkSpaces Maintenance Window Target A
      Description: This object binds Amazon WorkSpaces Maintenance Window A to the selected tagged instances
      WindowId:
        Ref: WKSMaintWindowA
      ResourceType: INSTANCE
      Targets:
      - Key: tag:MaintenanceWindow
        Values:
        - WKSMaintWindowA
      Name: WorkSpacesMaintenanceWindowTargetA
  WKSMaintWindowTargetB:
    Type: AWS::SSM::MaintenanceWindowTarget
    Properties:
      OwnerInformation: Amazon WorkSpaces Maintenance Window Target B
      Description: This object binds Amazon WorkSpaces Maintenance Window B to the selected tagged instances
      WindowId:
        Ref: WKSMaintWindowB
      ResourceType: INSTANCE
      Targets:
      - Key: tag:MaintenanceWindow
        Values:
        - WKSMaintWindowB
      Name: WorkSpacesMaintenanceWindowTargetB
  WKSMaintWindowTaskA1:
    Type: AWS::SSM::MaintenanceWindowTask
    Properties:
      MaxErrors: 50%
      Description: Amazon WorkSpaces OS Patching Task
      ServiceRoleArn:
        Fn::Join:
        - ''
        - - 'arn:aws:iam::'
          - Ref: AWS::AccountId
          - ":role/"
          - Ref: AWS::Region
          - "-"
          - roles_ssm_maintenance
      Priority: 1
      MaxConcurrency: 50%
      Targets:
      - Key: WindowTargetIds
        Values:
        - Ref: WKSMaintWindowTargetA
      Name: WorkSpacesMaintenanceOSPatching
      TaskArn: AWS-RunPatchBaseline
      WindowId:
        Ref: WKSMaintWindowA
      TaskType: RUN_COMMAND
      TaskInvocationParameters:
        MaintenanceWindowRunCommandParameters:
          TimeoutSeconds: 600
          OutputS3BucketName:
            Fn::Join:
            - "-"
            - - s3
              - Ref: AWS::AccountId
              - ssm-inventory-bucket          
          OutputS3KeyPrefix: tasklogs
          Parameters:
            Operation:
            - Install
  WKSMaintWindowTaskB1:
    Type: AWS::SSM::MaintenanceWindowTask
    Properties:
      MaxErrors: 50%
      Description: Euc OS Patching Task
      ServiceRoleArn:
        Fn::Join:
        - ''
        - - 'arn:aws:iam::'
          - Ref: AWS::AccountId
          - ":role/"
          - Ref: AWS::Region
          - "-"
          - roles_ssm_maintenance
      Priority: 1
      MaxConcurrency: 50%
      Targets:
      - Key: WindowTargetIds
        Values:
        - Ref: WKSMaintWindowTargetB
      Name: WorkSpacesMaintenanceOSPatching
      TaskArn: AWS-RunPatchBaseline
      WindowId:
        Ref: WKSMaintWindowB
      TaskType: RUN_COMMAND
      TaskInvocationParameters:
        MaintenanceWindowRunCommandParameters:
          TimeoutSeconds: 600
          OutputS3BucketName:
            Fn::Join:
            - "-"
            - - s3
              - Ref: AWS::AccountId
              - ssm-inventory-bucket
          OutputS3KeyPrefix: tasklogs
          Parameters:
            Operation:
            - Install
  InventoryAssociation:
    Type: AWS::SSM::Association
    Properties:
      AssociationName: InventoryAssociation
      Name: AWS-GatherSoftwareInventory
      Parameters:
        applications:
        - Enabled
        awsComponents:
        - Enabled
        networkConfig:
        - Enabled
        windowsUpdates:
        - Enabled
        instanceDetailedInformation:
        - Enabled
        services:
        - Enabled
        windowsRoles:
        - Enabled
        customInventory:
        - Enabled
      ScheduleExpression: cron(0 0/30 * 1/1 * ? *)
      Targets:
      - Key: InstanceIds
        Values:
        - "*"
Outputs:
  oWorkSpacesSSMInstanceRole:
    Value: 
        !If 
            - CreateManagedInstanceProfileCondition
            - 
                Fn::Join:
                - ''
                - - Ref: AWS::Region
                  - "-"
                  - role_ssm_manageinstances          
            - !Ref ExistingManagedInstanceProfile
    Description: The role for managed workspaces instances
    Export:
        Name: WorkSpacesSSMInstanceRole