SSM Quick SetupのHost Managementとほぼ同じ設定を大阪リージョンにも展開する

どうしても大阪リージョンにもHost Managementを展開したいときに役に立つかもしれません。
2023.08.10

はじめに

SSM Quick SetupのHost Managementは、SSM AgentやCloudWatch Agentの更新やインベントリの収集などEC2を管理する上で便利なものをサクッと展開できる優れものです。

設定できる内容を詳細に知りたい方はドキュメントをご覧ください。

このQuick Setupを使うと、Organizations環境の選択したOUとリージョンに設定を展開できるのですが、大阪リージョンを選ぼうとしたところ問題が発生しました。

ないんですよね、大阪リージョンが。

大阪リージョンからコンソールを確認すると、そもそもQuick Setupの欄がなかったので未対応のようです。

CLIにもQuick Setupの機能と思われるものがなく諦めようと思っていたところ、Quick Setupの実態がStackSetsによって展開されてることに気付きました。

StackSetsで展開されているということはテンプレートもあるはずです。

そのテンプレートを使えば手動で大阪リージョン含めて展開できるのでは…?と思い付いたのでやってみました。

やってみる

Quick Setupの機能で展開されているCloudFormationテンプレートを確認し、StackSetsで展開していきます。

CloudFormationテンプレートの確認

まずは展開されているCloudFormationテンプレートを確認します。

自分が設定したい項目でチェックをつけた状態でQuick SetupのHost Managementを設定しました。

設定が完了すると、CloudFormationコンソールのStackSetsにAWS-QuickSetup-SSMHostMgmt-XX-xxxxxの形式でStackSetが作成されています。 テンプレートタブを開くと、json形式で長いテンプレートが確認できました。

今回はこれを使って手動でStackSetsを作成していきます。

JSONからYAMLに変換したんですが超長いです。欲しい方は↓をクリックして確認してください。

Host Managementテンプレート
Metadata:
  Version: "3.1"
Parameters:
  QSType:
    Type: String
    AllowedValues:
      - LA
      - TA
      - MA
    Default: TA
    Description: "(Required) Specifies whether the Quick Setup applies to the local account or an AWS organization."
  QSConfigurationId:
    Type: String
    Default: ""
    Description: "(Required) Unique identifier of the deployed configuration."
  QSGlobalResourcesRegion:
    Type: String
    Default: ""
    Description: "(Required) Name of the AWS Region to deploy global resources such as S3 buckets."
  QSPrincipalOrgId:
    Type: String
    Default: ""
    Description: "(Optional) The ID of the principal organization your management account operates in."
  UpdateSsmAgent:
    Type: String
    Default: "true"
    AllowedValues:
      - "true"
      - "false"
    Description: "(Optional) Determines whether the SSM agent updates every 2 weeks."
  UpdateEc2LaunchAgent:
    Type: String
    Default: "false"
    AllowedValues:
      - "true"
      - "false"
    Description: "(Optional) Determines whether the EC2Launch agent updates monthly."
  CollectInventory:
    Type: String
    Default: "true"
    AllowedValues:
      - "true"
      - "false"
    Description: "(Optional) Determines whether inventory is collected every 30 minutes."
  ScanInstances:
    Type: String
    Default: "true"
    AllowedValues:
      - "true"
      - "false"
    Description: "(Optional) Determines whether instances are scanned for patches daily."
  InstallCloudWatchAgent:
    Type: String
    Default: "false"
    AllowedValues:
      - "true"
      - "false"
    Description: "(Optional) Whether the CloudWatch agent should be installed."
  UpdateCloudWatchAgent:
    Type: String
    Default: "false"
    AllowedValues:
      - "true"
      - "false"
    Description: "(Optional) Determines whether the CloudWatch agent updates monthly."
  IsPolicyAttachAllowed:
    Type: String
    Default: "false"
    AllowedValues:
      - "true"
      - "false"
    Description: "(Optional) Whether you want to allow Quick Setup to attach IAM policies to existing instance profiles."
  ProvidedInstanceProfileName:
    Type: String
    Default: ""
    Description: "(Optional) The name of the instance profile. This parameter is only used for the local Quick Setup type."
  ProvidedAssumeRoleArn:
    Type: String
    Default: "*"
    Description: "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. This parameter is only used for the local Quick Setup type."
  TargetType:
    Type: String
    Default: "*"
    AllowedValues:
      - Tags
      - InstanceIds
      - "*"
      - ResourceGroups
    Description: "(Optional) Specifies the way instances are targeted. This parameter is only used for the local Quick Setup type."
  TargetInstances:
    Type: String
    Default: "*"
    Description: "(Optional) Specifies the target instances. This parameter is only used for the local Quick Setup type when InstanceIds are the TargetType."
  TargetTagKey:
    Type: String
    Default: ""
    Description: "(Optional) Specifies the tag key used to target instances. This parameter is only used for the local Quick Setup type when Tags are the TargetType."
  TargetTagValue:
    Type: String
    Default: ""
    Description: "(Optional) Specifies the tag value used to target instances. This parameter is only used for the local Quick Setup type when Tags are the TargetType."
  ResourceGroupName:
    Type: String
    Default: ""
    Description: "(Optional) Specifies the tag value for the resource group used to target instances. This parameter is only used for the local Quick Setup type when ResourceGroups are the TargetType."
Conditions:
  CreateUpdateSsmAgentAssociation:
    "Fn::Equals":
      - Ref: UpdateSsmAgent
      - "true"
  CreateUpdateEc2LaunchAgentAssociation:
    "Fn::Equals":
      - Ref: UpdateEc2LaunchAgent
      - "true"
  CreateCollectInventoryAssociation:
    "Fn::Equals":
      - Ref: CollectInventory
      - "true"
  CreateScanInstancesAssociation:
    "Fn::Equals":
      - Ref: ScanInstances
      - "true"
  CreateInstallAndManageCloudWatchAgentAssociation:
    "Fn::Equals":
      - Ref: InstallCloudWatchAgent
      - "true"
  UpdateCloudWatchAgentAssociation:
    "Fn::Equals":
      - Ref: UpdateCloudWatchAgent
      - "true"
  ShouldUpdateCloudWatchAgent:
    "Fn::Equals":
      - Ref: UpdateCloudWatchAgent
      - "true"
  AtLeastOneAssociationCreated:
    "Fn::Or":
      - "Fn::Equals":
          - Ref: UpdateSsmAgent
          - "true"
      - "Fn::Equals":
          - Ref: UpdateEc2LaunchAgent
          - "true"
      - "Fn::Equals":
          - Ref: CollectInventory
          - "true"
      - "Fn::Equals":
          - Ref: ScanInstances
          - "true"
      - "Fn::Equals":
          - Ref: InstallCloudWatchAgent
          - "true"
      - "Fn::Equals":
          - Ref: UpdateCloudWatchAgent
          - "true"
  IsTagValueNotSpecified:
    "Fn::Equals":
      - Ref: TargetTagValue
      - ""
  IsTagKeyAndValueTargeted:
    "Fn::And":
      - "Fn::Equals":
          - Ref: QSType
          - LA
      - "Fn::Equals":
          - Ref: TargetType
          - Tags
      - "Fn::Not":
          - Condition: IsTagValueNotSpecified
  IsTagKeyOnlyTargeted:
    "Fn::And":
      - "Fn::Equals":
          - Ref: QSType
          - LA
      - "Fn::Equals":
          - Ref: TargetType
          - Tags
      - Condition: IsTagValueNotSpecified
  IsResourceGroupTargeted:
    "Fn::And":
      - "Fn::Equals":
          - Ref: QSType
          - LA
      - "Fn::Equals":
          - Ref: TargetType
          - ResourceGroups
  IsOrgQuickSetup:
    "Fn::Equals":
      - Ref: QSType
      - TA
  IsNoAutomationAssumeRoleProvided:
    "Fn::Or":
      - "Fn::Equals":
          - Ref: QSType
          - TA
      - "Fn::Equals":
          - Ref: ProvidedAssumeRoleArn
          - "*"
  IsNoInstanceProfileProvided:
    "Fn::Or":
      - "Fn::Equals":
          - Ref: QSType
          - TA
      - "Fn::Equals":
          - Ref: ProvidedInstanceProfileName
          - ""
  IsInstanceProfileProvided:
    "Fn::Not":
      - Condition: IsNoInstanceProfileProvided
  TargetAllAutomation:
    "Fn::Equals":
      - Ref: TargetInstances
      - "*"
  TargetAll:
    "Fn::Equals":
      - Ref: TargetInstances
      - "*"
  PolicyAttachAllowed:
    "Fn::Equals":
      - Ref: IsPolicyAttachAllowed
      - "true"
Resources:
  RoleForAutomation:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ssm.amazonaws.com
            Action:
              - "sts:AssumeRole"
      Policies:
        - PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - "iam:ListRoles"
                  - "config:DescribeConfigurationRecorders"
                  - "compute-optimizer:GetEnrollmentStatus"
                  - "support:DescribeTrustedAdvisorChecks"
                Resource: "*"
              - Effect: Allow
                Action:
                  - "ssm:UpdateServiceSetting"
                  - "ssm:GetServiceSetting"
                Resource:
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":ssm:*:*:servicesetting/ssm/opsitem/ssm-patchmanager"
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":ssm:*:*:servicesetting/ssm/opsitem/EC2"
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":ssm:*:*:servicesetting/ssm/opsdata/ExplorerOnboarded"
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":ssm:*:*:servicesetting/ssm/opsdata/Association"
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":ssm:*:*:servicesetting/ssm/opsdata/ComputeOptimizer"
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":ssm:*:*:servicesetting/ssm/opsdata/ConfigCompliance"
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":ssm:*:*:servicesetting/ssm/opsdata/OpsData-TrustedAdvisor"
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":ssm:*:*:servicesetting/ssm/opsdata/SupportCenterCase"
              - Effect: Allow
                Action:
                  - "iam:CreateServiceLinkedRole"
                Resource:
                  "Fn::Join":
                    - ""
                    - - "arn:"
                      - Ref: "AWS::Partition"
                      - ":iam::*:role/aws-service-role/ssm."
                      - Ref: "AWS::URLSuffix"
                      - /AWSServiceRoleForAmazonSSM
                Condition:
                  StringEquals:
                    "iam:AWSServiceName": ssm.amazonaws.com
          PolicyName: SSMQuickSetupEnableExplorerInlinePolicy
        - PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - "ssm:GetAutomationExecution"
                  - "ec2:DescribeIamInstanceProfileAssociations"
                  - "ec2:DisassociateIamInstanceProfile"
                  - "ec2:DescribeInstances"
                  - "ssm:StartAutomationExecution"
                  - "iam:GetInstanceProfile"
                  - "iam:ListInstanceProfilesForRole"
                Resource: "*"
              - Effect: Allow
                Action:
                  - "iam:AttachRolePolicy"
                Resource:
                  - "Fn::If":
                      - PolicyAttachAllowed
                      - "*"
                      - "Fn::Join":
                          - ""
                          - - "arn:"
                            - Ref: "AWS::Partition"
                            - ":iam::"
                            - Ref: "AWS::AccountId"
                            - ":role/AmazonSSMRoleForInstancesQuickSetup"
                Condition:
                  ArnEquals:
                    "iam:PolicyARN":
                      - "Fn::Join":
                          - ""
                          - - "arn:"
                            - Ref: "AWS::Partition"
                            - ":iam::aws:policy/AmazonSSMManagedInstanceCore"
                      - "Fn::Join":
                          - ""
                          - - "arn:"
                            - Ref: "AWS::Partition"
                            - ":iam::aws:policy/AmazonSSMPatchAssociation"
              - Effect: Allow
                Action:
                  - "iam:AddRoleToInstanceProfile"
                Resource:
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":iam::"
                        - Ref: "AWS::AccountId"
                        - ":instance-profile/AmazonSSMRoleForInstancesQuickSetup"
              - Effect: Allow
                Action:
                  - "ec2:AssociateIamInstanceProfile"
                Resource: "*"
                Condition:
                  StringEquals:
                    "ec2:NewInstanceProfile":
                      "Fn::Join":
                        - ""
                        - - "arn:"
                          - Ref: "AWS::Partition"
                          - ":iam::"
                          - Ref: "AWS::AccountId"
                          - ":instance-profile/AmazonSSMRoleForInstancesQuickSetup"
              - Effect: Allow
                Action:
                  - "iam:CreateInstanceProfile"
                Resource:
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":iam::"
                        - Ref: "AWS::AccountId"
                        - ":instance-profile/AmazonSSMRoleForInstancesQuickSetup"
              - Effect: Allow
                Action:
                  - "iam:GetRole"
                Resource:
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":iam::"
                        - Ref: "AWS::AccountId"
                        - ":role/AmazonSSMRoleForInstancesQuickSetup"
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":iam::"
                        - Ref: "AWS::AccountId"
                        - ":role/AWS-QuickSetup-HostMgmtRole-"
                        - Ref: "AWS::Region"
                        - "-"
                        - Ref: QSConfigurationId
              - Effect: Allow
                Action:
                  - "iam:PassRole"
                Resource:
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":iam::"
                        - Ref: "AWS::AccountId"
                        - ":role/AmazonSSMRoleForInstancesQuickSetup"
                Condition:
                  StringEquals:
                    "iam:PassedToService":
                      - ec2.amazonaws.com
              - Effect: Allow
                Action:
                  - "iam:PassRole"
                Resource:
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":iam::"
                        - Ref: "AWS::AccountId"
                        - ":role/AWS-QuickSetup-HostMgmtRole-"
                        - Ref: "AWS::Region"
                        - "-"
                        - Ref: QSConfigurationId
                Condition:
                  StringEquals:
                    "iam:PassedToService":
                      - ssm.amazonaws.com
              - Effect: Allow
                Action:
                  - "iam:CreateRole"
                Resource:
                  - "Fn::Join":
                      - ""
                      - - "arn:"
                        - Ref: "AWS::Partition"
                        - ":iam::"
                        - Ref: "AWS::AccountId"
                        - ":role/AmazonSSMRoleForInstancesQuickSetup"
          PolicyName:
            "Fn::Join":
              - ""
              - - AWS-QuickSetup-SSMHostMgmt-CreateAndAttachRoleInlinePolicy-
                - Ref: "AWS::Region"
                - "-"
                - Ref: QSConfigurationId
      RoleName:
        "Fn::Join":
          - ""
          - - AWS-QuickSetup-HostMgmtRole-
            - Ref: "AWS::Region"
            - "-"
            - Ref: QSConfigurationId
  CreateAndAttachIAMToInstance:
    Type: "AWS::SSM::Document"
    Properties:
      UpdateMethod: NewVersion
      Content:
        description: "Composite document for Quick Setup Managing Instances association. This document ensures IAM role for instance profile is created in account with all required policies"
        schemaVersion: "0.3"
        assumeRole: "{{AutomationAssumeRole}}"
        parameters:
          AutomationAssumeRole:
            type: String
          InstanceId:
            type: String
          IsPolicyAttachAllowed:
            type: String
        mainSteps:
          - name: getExistingRoleName
            action: "aws:executeScript"
            inputs:
              Runtime: python3.6
              Handler: getInstanceProfileName
              InputPayload:
                InstanceId: "{{InstanceId}}"
              Script: "import boto3\n\ndef getInstanceProfileName(events, context):\n    ec2_client = boto3.client(\"ec2\")\n    response = ec2_client.describe_instances(InstanceIds=[events[\"InstanceId\"]])\n    if 'IamInstanceProfile' in response['Reservations'][0]['Instances'][0]:\n        return {'RoleName': response['Reservations'][0]['Instances'][0]['IamInstanceProfile']['Arn'].split('/').pop()}\n    return {'RoleName': 'NoRoleFound'}"
            outputs:
              - Name: existingInstanceProfileRoleName
                Selector: $.Payload.RoleName
                Type: String
            nextStep: branchIfProfileExists
          - name: branchIfProfileExists
            action: "aws:branch"
            inputs:
              Choices:
                - NextStep: createRoleIfNotExists
                  Variable: "{{getExistingRoleName.existingInstanceProfileRoleName}}"
                  StringEquals: NoRoleFound
              Default: checkIfPolicyAttachAllowed
          - name: checkIfPolicyAttachAllowed
            action: "aws:branch"
            inputs:
              Choices:
                - NextStep: getRoleFromInstanceProfile
                  Variable: "{{IsPolicyAttachAllowed}}"
                  StringEquals: "true"
              Default: createRoleIfNotExists
          - name: getRoleFromInstanceProfile
            action: "aws:executeAwsApi"
            inputs:
              Service: iam
              Api: GetInstanceProfile
              InstanceProfileName: "{{getExistingRoleName.existingInstanceProfileRoleName}}"
            outputs:
              - Name: existingRoleName
                Selector: "$.InstanceProfile.Roles[0].RoleName"
                Type: String
            nextStep: attachAmazonSSMManagedInstanceCoreToExistingRole
          - name: attachAmazonSSMManagedInstanceCoreToExistingRole
            action: "aws:executeAwsApi"
            inputs:
              Service: iam
              Api: AttachRolePolicy
              RoleName: "{{getRoleFromInstanceProfile.existingRoleName}}"
              PolicyArn: "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
            nextStep: attachAmazonSSMPatchAssociationToExistingRole
          - name: attachAmazonSSMPatchAssociationToExistingRole
            action: "aws:executeAwsApi"
            inputs:
              Service: iam
              Api: AttachRolePolicy
              RoleName: "{{getRoleFromInstanceProfile.existingRoleName}}"
              PolicyArn: "arn:aws:iam::aws:policy/AmazonSSMPatchAssociation"
            isEnd: true
          - name: createRoleIfNotExists
            action: "aws:executeAwsApi"
            inputs:
              Service: iam
              Api: CreateRole
              Path: /
              RoleName: AmazonSSMRoleForInstancesQuickSetup
              AssumeRolePolicyDocument: '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ec2.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
              Description: "EC2 role for SSM for Quick-Setup"
            description: "Create AmazonSSMRoleForInstancesQuickSetup Role For SSM Quick Setup"
            onFailure: Continue
            nextStep: assertRoleForInstanceProfileExists
          - name: assertRoleForInstanceProfileExists
            action: "aws:assertAwsResourceProperty"
            inputs:
              Service: iam
              Api: GetRole
              PropertySelector: $.Role.RoleName
              DesiredValues:
                - AmazonSSMRoleForInstancesQuickSetup
              RoleName: AmazonSSMRoleForInstancesQuickSetup
            nextStep: attachAmazonSSMManagedInstanceCoreToRole
          - name: attachAmazonSSMManagedInstanceCoreToRole
            action: "aws:executeAwsApi"
            inputs:
              Service: iam
              Api: AttachRolePolicy
              RoleName: AmazonSSMRoleForInstancesQuickSetup
              PolicyArn: "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
            nextStep: attachAmazonSSMPatchAssociationToRole
          - name: attachAmazonSSMPatchAssociationToRole
            action: "aws:executeAwsApi"
            inputs:
              Service: iam
              Api: AttachRolePolicy
              RoleName: AmazonSSMRoleForInstancesQuickSetup
              PolicyArn: "arn:aws:iam::aws:policy/AmazonSSMPatchAssociation"
            nextStep: createInstanceProfileIfNotExists
          - name: createInstanceProfileIfNotExists
            action: "aws:executeAwsApi"
            inputs:
              InstanceProfileName: AmazonSSMRoleForInstancesQuickSetup
              Service: iam
              Api: CreateInstanceProfile
            onFailure: Continue
            nextStep: addRoleToInstanceProfile
          - name: addRoleToInstanceProfile
            action: "aws:executeAwsApi"
            inputs:
              InstanceProfileName: AmazonSSMRoleForInstancesQuickSetup
              RoleName: AmazonSSMRoleForInstancesQuickSetup
              Service: iam
              Api: AddRoleToInstanceProfile
            onFailure: Continue
            nextStep: executeAttachIAMToInstance
          - name: executeAttachIAMToInstance
            action: "aws:executeAutomation"
            maxAttempts: 10
            timeoutSeconds: 60
            inputs:
              DocumentName: AWS-AttachIAMToInstance
              RuntimeParameters:
                RoleName: AmazonSSMRoleForInstancesQuickSetup
                ForceReplace: false
                AutomationAssumeRole: "{{ AutomationAssumeRole }}"
                InstanceId: "{{ InstanceId }}"
            isEnd: true
      DocumentType: Automation
      Name:
        "Fn::Sub": "AWSQuickSetup-CreateAndAttachIAMToInstance-${QSConfigurationId}"
      TargetType: "/AWS::EC2::Instance"
  UpdateExistingInstanceProfile:
    Type: "AWS::SSM::Document"
    Properties:
      UpdateMethod: NewVersion
      Content:
        description: "Composite document for Quick Setup Managing Instances association. This document updates the user provided instance profile with roles and policies"
        schemaVersion: "0.3"
        assumeRole: "{{AutomationAssumeRole}}"
        parameters:
          AutomationAssumeRole:
            type: String
          InstanceId:
            type: String
          InstanceProfile:
            type: String
        mainSteps:
          - name: getRoleFromInstanceProfile
            action: "aws:executeAwsApi"
            inputs:
              Service: iam
              Api: GetInstanceProfile
              InstanceProfileName: "{{InstanceProfile}}"
            outputs:
              - Name: existingRoleName
                Selector: "$.InstanceProfile.Roles[0].RoleName"
                Type: String
            nextStep: attachAmazonSSMManagedInstanceCoreToExistingRole
          - name: attachAmazonSSMManagedInstanceCoreToExistingRole
            action: "aws:executeAwsApi"
            inputs:
              Service: iam
              Api: AttachRolePolicy
              RoleName: "{{getRoleFromInstanceProfile.existingRoleName}}"
              PolicyArn: "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
            nextStep: attachAmazonSSMPatchAssociationToExistingRole
          - name: attachAmazonSSMPatchAssociationToExistingRole
            action: "aws:executeAwsApi"
            inputs:
              Service: iam
              Api: AttachRolePolicy
              RoleName: "{{getRoleFromInstanceProfile.existingRoleName}}"
              PolicyArn: "arn:aws:iam::aws:policy/AmazonSSMPatchAssociation"
            isEnd: true
      DocumentType: Automation
      Name:
        "Fn::Sub": "AWSQuickSetup-UpdateExistingInstanceProfile-${QSConfigurationId}"
      TargetType: "/AWS::EC2::Instance"
  SystemAssociationForManagingInstances:
    Type: "AWS::SSM::Association"
    Properties:
      Name:
        Ref: CreateAndAttachIAMToInstance
      AssociationName:
        "Fn::Join":
          - ""
          - - AWS-QuickSetup-SSMHostMgmt-AttachIAMToInstance-
            - Ref: QSConfigurationId
      Parameters:
        AutomationAssumeRole:
          - "Fn::If":
              - IsNoAutomationAssumeRoleProvided
              - "Fn::GetAtt":
                  - RoleForAutomation
                  - Arn
              - Ref: ProvidedAssumeRoleArn
        IsPolicyAttachAllowed:
          - Ref: IsPolicyAttachAllowed
      AutomationTargetParameterName: InstanceId
      Targets:
        "Fn::If":
          - IsOrgQuickSetup
          - - Key: InstanceIds
              Values:
                - "*"
          - "Fn::If":
              - IsTagKeyAndValueTargeted
              - - Key:
                    "Fn::Join":
                      - ""
                      - - "tag:"
                        - Ref: TargetTagKey
                  Values:
                    - Ref: TargetTagValue
              - "Fn::If":
                  - IsTagKeyOnlyTargeted
                  - - Key: tag-key
                      Values:
                        - Ref: TargetTagKey
                  - "Fn::If":
                      - IsResourceGroupTargeted
                      - - Key: ResourceGroup
                          Values:
                            - Ref: ResourceGroupName
                      - "Fn::If":
                          - TargetAll
                          - - Key: InstanceIds
                              Values:
                                - "*"
                          - - Key: ParameterValues
                              Values:
                                "Fn::Split":
                                  - ","
                                  - Ref: TargetInstances
      ScheduleExpression: "rate(30 days)"
    Condition: IsNoInstanceProfileProvided
  SystemAssociationForUpdateManagingInstances:
    Type: "AWS::SSM::Association"
    Properties:
      Name:
        Ref: UpdateExistingInstanceProfile
      AssociationName:
        "Fn::Join":
          - ""
          - - AWS-QuickSetup-SSMHostMgmt-UpdateIAMForInstanceMgmt-
            - Ref: QSConfigurationId
      Parameters:
        AutomationAssumeRole:
          - "Fn::If":
              - IsNoAutomationAssumeRoleProvided
              - "Fn::GetAtt":
                  - RoleForAutomation
                  - Arn
              - Ref: ProvidedAssumeRoleArn
        InstanceProfile:
          - Ref: ProvidedInstanceProfileName
      AutomationTargetParameterName: InstanceId
      Targets:
        "Fn::If":
          - IsOrgQuickSetup
          - - Key: InstanceIds
              Values:
                - "*"
          - "Fn::If":
              - IsTagKeyAndValueTargeted
              - - Key:
                    "Fn::Join":
                      - ""
                      - - "tag:"
                        - Ref: TargetTagKey
                  Values:
                    - Ref: TargetTagValue
              - "Fn::If":
                  - IsTagKeyOnlyTargeted
                  - - Key: tag-key
                      Values:
                        - Ref: TargetTagKey
                  - "Fn::If":
                      - IsResourceGroupTargeted
                      - - Key: ResourceGroup
                          Values:
                            - Ref: ResourceGroupName
                      - "Fn::If":
                          - TargetAll
                          - - Key: InstanceIds
                              Values:
                                - "*"
                          - - Key: ParameterValues
                              Values:
                                "Fn::Split":
                                  - ","
                                  - Ref: TargetInstances
      ScheduleExpression: "rate(30 days)"
    Condition: IsInstanceProfileProvided
  # SystemAssociationForEnablingExplorer:
  #   Type: "AWS::SSM::Association"
  #   Properties:
  #     Name: AWS-EnableExplorer
  #     AssociationName:
  #       "Fn::Join":
  #         - ""
  #         - - AWS-QuickSetup-SSMHostMgmt-EnableExplorer-
  #           - Ref: QSConfigurationId
  #     Parameters:
  #       AutomationAssumeRole:
  #         - "Fn::If":
  #             - IsNoAutomationAssumeRoleProvided
  #             - "Fn::GetAtt":
  #                 - RoleForAutomation
  #                 - Arn
  #             - Ref: ProvidedAssumeRoleArn
  #   Condition: AtLeastOneAssociationCreated
  SystemAssociationForSsmAgentUpdate:
    Type: "AWS::SSM::Association"
    Properties:
      Name: AWS-UpdateSSMAgent
      AssociationName:
        "Fn::Join":
          - ""
          - - AWS-QuickSetup-SSMHostMgmt-UpdateSSMAgent-
            - Ref: QSConfigurationId
      ScheduleExpression: "rate(14 days)"
      Targets:
        "Fn::If":
          - IsOrgQuickSetup
          - - Key: InstanceIds
              Values:
                - "*"
          - "Fn::If":
              - IsTagKeyAndValueTargeted
              - - Key:
                    "Fn::Join":
                      - ""
                      - - "tag:"
                        - Ref: TargetTagKey
                  Values:
                    - Ref: TargetTagValue
              - "Fn::If":
                  - IsTagKeyOnlyTargeted
                  - - Key: tag-key
                      Values:
                        - Ref: TargetTagKey
                  - "Fn::If":
                      - IsResourceGroupTargeted
                      - - Key: "resource-groups:Name"
                          Values:
                            - Ref: ResourceGroupName
                      - "Fn::If":
                          - TargetAll
                          - - Key: InstanceIds
                              Values:
                                - "*"
                          - - Key: InstanceIds
                              Values:
                                "Fn::Split":
                                  - ","
                                  - Ref: TargetInstances
    Condition: CreateUpdateSsmAgentAssociation
  SystemAssociationForEc2LaunchAgentUpdate:
    Type: "AWS::SSM::Association"
    Properties:
      Name: AWSEC2-UpdateLaunchAgent
      AssociationName:
        "Fn::Join":
          - ""
          - - AWS-QuickSetup-SSMHostMgmt-UpdateEC2LaunchAgent-
            - Ref: QSConfigurationId
      ScheduleExpression: "rate(30 days)"
      Targets:
        "Fn::If":
          - IsOrgQuickSetup
          - - Key: InstanceIds
              Values:
                - "*"
          - "Fn::If":
              - IsTagKeyAndValueTargeted
              - - Key:
                    "Fn::Join":
                      - ""
                      - - "tag:"
                        - Ref: TargetTagKey
                  Values:
                    - Ref: TargetTagValue
              - "Fn::If":
                  - IsTagKeyOnlyTargeted
                  - - Key: tag-key
                      Values:
                        - Ref: TargetTagKey
                  - "Fn::If":
                      - IsResourceGroupTargeted
                      - - Key: "resource-groups:Name"
                          Values:
                            - Ref: ResourceGroupName
                      - "Fn::If":
                          - TargetAll
                          - - Key: InstanceIds
                              Values:
                                - "*"
                          - - Key: InstanceIds
                              Values:
                                "Fn::Split":
                                  - ","
                                  - Ref: TargetInstances
    Condition: CreateUpdateEc2LaunchAgentAssociation
  SystemAssociationForInventoryCollection:
    Type: "AWS::SSM::Association"
    Properties:
      Name: AWS-GatherSoftwareInventory
      AssociationName:
        "Fn::Join":
          - ""
          - - AWS-QuickSetup-SSMHostMgmt-CollectInventory-
            - Ref: QSConfigurationId
      Parameters:
        applications:
          - Enabled
        awsComponents:
          - Enabled
        networkConfig:
          - Enabled
        instanceDetailedInformation:
          - Enabled
        windowsUpdates:
          - Enabled
        services:
          - Enabled
        windowsRoles:
          - Enabled
        customInventory:
          - Enabled
      ScheduleExpression: "rate(30 minutes)"
      Targets:
        "Fn::If":
          - IsOrgQuickSetup
          - - Key: InstanceIds
              Values:
                - "*"
          - "Fn::If":
              - IsTagKeyAndValueTargeted
              - - Key:
                    "Fn::Join":
                      - ""
                      - - "tag:"
                        - Ref: TargetTagKey
                  Values:
                    - Ref: TargetTagValue
              - "Fn::If":
                  - IsTagKeyOnlyTargeted
                  - - Key: tag-key
                      Values:
                        - Ref: TargetTagKey
                  - "Fn::If":
                      - IsResourceGroupTargeted
                      - - Key: "resource-groups:Name"
                          Values:
                            - Ref: ResourceGroupName
                      - "Fn::If":
                          - TargetAll
                          - - Key: InstanceIds
                              Values:
                                - "*"
                          - - Key: InstanceIds
                              Values:
                                "Fn::Split":
                                  - ","
                                  - Ref: TargetInstances
    Condition: CreateCollectInventoryAssociation
  SystemAssociationForScanningPatches:
    Type: "AWS::SSM::Association"
    Properties:
      Name: AWS-RunPatchBaselineAssociation
      AssociationName:
        "Fn::Join":
          - ""
          - - AWS-QuickSetup-SSMHostMgmt-ScanForPatches-
            - Ref: QSConfigurationId
      Parameters:
        Operation:
          - Scan
      ScheduleExpression: "rate(1 day)"
      SyncCompliance: MANUAL
      Targets:
        "Fn::If":
          - IsOrgQuickSetup
          - - Key: InstanceIds
              Values:
                - "*"
          - "Fn::If":
              - IsTagKeyAndValueTargeted
              - - Key:
                    "Fn::Join":
                      - ""
                      - - "tag:"
                        - Ref: TargetTagKey
                  Values:
                    - Ref: TargetTagValue
              - "Fn::If":
                  - IsTagKeyOnlyTargeted
                  - - Key: tag-key
                      Values:
                        - Ref: TargetTagKey
                  - "Fn::If":
                      - IsResourceGroupTargeted
                      - - Key: "resource-groups:Name"
                          Values:
                            - Ref: ResourceGroupName
                      - "Fn::If":
                          - TargetAll
                          - - Key: InstanceIds
                              Values:
                                - "*"
                          - - Key: InstanceIds
                              Values:
                                "Fn::Split":
                                  - ","
                                  - Ref: TargetInstances
    Condition: CreateScanInstancesAssociation
  InstallAndManageCloudWatchDocument:
    Type: "AWS::SSM::Document"
    Properties:
      UpdateMethod: NewVersion
      Content:
        schemaVersion: "2.2"
        description: "The AWS-InstallAndManageCloudWatch command document installs the Amazon CloudWatch agent and manages the configuration of the agent for Amazon EC2 instances."
        mainSteps:
          - action: "aws:runDocument"
            name: installCWAgent
            inputs:
              documentType: SSMDocument
              documentPath: AWS-ConfigureAWSPackage
              documentParameters:
                action: Install
                name: AmazonCloudWatchAgent
          - action: "aws:runDocument"
            name: manageCWAgent
            inputs:
              documentType: SSMDocument
              documentPath: AmazonCloudWatch-ManageAgent
              documentParameters:
                action: configure
                mode: ec2
                optionalConfigurationSource: default
                optionalRestart: "yes"
      DocumentType: Command
      Name:
        "Fn::Join":
          - ""
          - - AWSQuickSetup-InstallAndManageCloudWatchDocument-
            - Ref: QSConfigurationId
    Condition: CreateInstallAndManageCloudWatchAgentAssociation
  SystemAssociationForInstallAndConfigureCloudWatchAgent:
    Type: "AWS::SSM::Association"
    Properties:
      Name:
        Ref: InstallAndManageCloudWatchDocument
      AssociationName:
        "Fn::Join":
          - ""
          - - AWS-QuickSetup-SSMHostMgmt-ManageCloudWatchAgent-
            - Ref: QSConfigurationId
      ScheduleExpression:
        Ref: "AWS::NoValue"
      Targets:
        "Fn::If":
          - IsOrgQuickSetup
          - - Key: InstanceIds
              Values:
                - "*"
          - "Fn::If":
              - IsTagKeyAndValueTargeted
              - - Key:
                    "Fn::Join":
                      - ""
                      - - "tag:"
                        - Ref: TargetTagKey
                  Values:
                    - Ref: TargetTagValue
              - "Fn::If":
                  - IsTagKeyOnlyTargeted
                  - - Key: tag-key
                      Values:
                        - Ref: TargetTagKey
                  - "Fn::If":
                      - IsResourceGroupTargeted
                      - - Key: "resource-groups:Name"
                          Values:
                            - Ref: ResourceGroupName
                      - "Fn::If":
                          - TargetAll
                          - - Key: InstanceIds
                              Values:
                                - "*"
                          - - Key: InstanceIds
                              Values:
                                "Fn::Split":
                                  - ","
                                  - Ref: TargetInstances
    Condition: CreateInstallAndManageCloudWatchAgentAssociation
  UpdateCloudWatchDocument:
    Type: "AWS::SSM::Document"
    Properties:
      UpdateMethod: NewVersion
      Content:
        schemaVersion: "2.2"
        description: "A composite document for updating CloudWatch agent."
        mainSteps:
          - precondition:
              StringEquals:
                - platformType
                - Linux
            action: "aws:runShellScript"
            name: first
            inputs:
              runCommand:
                - "sleep 1800"
          - precondition:
              StringEquals:
                - platformType
                - Windows
            action: "aws:runPowerShellScript"
            name: second
            inputs:
              runCommand:
                - "Start-Sleep -Seconds 1800"
          - action: "aws:runDocument"
            name: installCWAgent
            inputs:
              documentType: SSMDocument
              documentPath: AWS-ConfigureAWSPackage
              documentParameters: '{"action":"Install","name" : "AmazonCloudWatchAgent"}'
      DocumentType: Command
      Name:
        "Fn::Join":
          - ""
          - - UpdateCloudWatchDocument-
            - Ref: QSConfigurationId
    Condition: UpdateCloudWatchAgentAssociation
  SystemAssociationForUpdateCloudWatchAgent:
    Type: "AWS::SSM::Association"
    Properties:
      Name:
        Ref: UpdateCloudWatchDocument
      AssociationName:
        "Fn::Join":
          - ""
          - - AWS-QuickSetup-SSMHostMgmt-UpdateCloudWatchAgent-
            - Ref: QSConfigurationId
      ScheduleExpression: "rate(30 days)"
      Targets:
        "Fn::If":
          - IsOrgQuickSetup
          - - Key: InstanceIds
              Values:
                - "*"
          - "Fn::If":
              - IsTagKeyAndValueTargeted
              - - Key:
                    "Fn::Join":
                      - ""
                      - - "tag:"
                        - Ref: TargetTagKey
                  Values:
                    - Ref: TargetTagValue
              - "Fn::If":
                  - IsTagKeyOnlyTargeted
                  - - Key: tag-key
                      Values:
                        - Ref: TargetTagKey
                  - "Fn::If":
                      - IsResourceGroupTargeted
                      - - Key: "resource-groups:Name"
                          Values:
                            - Ref: ResourceGroupName
                      - "Fn::If":
                          - TargetAll
                          - - Key: InstanceIds
                              Values:
                                - "*"
                          - - Key: InstanceIds
                              Values:
                                "Fn::Split":
                                  - ","
                                  - Ref: TargetInstances
    Condition: UpdateCloudWatchAgentAssociation

後で解説するのですが、大阪リージョンに展開できないリソースがあったので一部コメントアウトしてます。

StackSetsの展開

テンプレートが取得できたので、StackSetsで展開していきます。

AWSコンソールから CloudFormation > StackSets > StackSet の作成 からテンプレートをアップロードします。

Stack名はAWS-QuickSetup-SSMHostMgmt-TA-xxxxの形式でxxxxには任意の文字列を入れてださい。

パラメータは先ほどQuick SetupのHost Managementから展開した時のStackSetのものと同じものを入力します。各パラメータのDescriptionを日本語訳したので置いておきます。値はサンプルとして私が検証時に入力した値です。

Key Description (日本語) 備考
QSType 必須) Quick Setupがローカルアカウントに適用されるか、AWS組織に適用されるかを指定します。 TA 組織内へ展開するならTA
QSConfigurationId 必須) デプロイされた設定の一意の識別子。 xxxx スタック名に入力したものと同様
QSGlobalResourcesRegion 必須) S3バケットなどのグローバルリソースをデプロイするAWS Regionの名前。 ap-northeast-1
QSPrincipalOrgId オプション) 管理アカウントが運用する主要組織のID。 o-xxxxxxxxxxx 組織ID
UpdateSsmAgent オプション) SSMエージェントが2週間ごとに更新されるかどうかを決定します。 true
UpdateEc2LaunchAgent オプション) EC2Launchエージェントが月に一度更新されるかどうかを決定します。 true
CollectInventory オプション) インベントリが30分ごとに収集されるかどうかを決定します。 true
ScanInstances オプション) インスタンスが毎日パッチのスキャンを行うかどうかを決定します。 true
InstallCloudWatchAgent オプション) CloudWatchエージェントをインストールするかどうか。 true
UpdateCloudWatchAgent オプション) CloudWatchエージェントが月に一度更新されるかどうかを決定します。 true
IsPolicyAttachAllowed オプション) Quick Setupに既存のインスタンスプロファイルにIAMポリシーをアタッチすることを許可するかどうか。 true
ProvidedInstanceProfileName オプション) インスタンスプロファイルの名前。このパラメータはローカルのQuick Setupタイプでのみ使用されます。
ProvidedAssumeRoleArn オプション) Automationが代わりにアクションを実行することを許可するロールのARN。このパラメータはローカルのQuick Setupタイプでのみ使用されます。 *
TargetType オプション) インスタンスがどのようにターゲットにされるかを指定します。このパラメータはローカルのQuick Setupタイプでのみ使用されます。 *
TargetInstances オプション) ターゲットとなるインスタンスを指定します。このパラメータは、InstanceIdsがTargetTypeである場合にローカルのQuick Setupタイプでのみ使用されます。 *
TargetTagKey オプション) インスタンスをターゲットにするために使用されるタグキーを指定します。このパラメータは、TagsがTargetTypeである場合にローカルのQuick Setupタイプでのみ使用されます。
TargetTagValue オプション) インスタンスをターゲットにするために使用されるタグの値を指定します。このパラメータは、TagsがTargetTypeである場合にローカルのQuick Setupタイプでのみ使用されます。
ResourceGroupName オプション) インスタンスをターゲットにするために使用されるリソースグループのタグ値を指定します。このパラメータは、ResourceGroupsがTargetTypeである場合にローカルのQuick Setupタイプでのみ使用されます。

次に展開先のOUやリージョンを入力します。1つのOUで東京と大阪リージョンに展開してみます。

他の値はデフォルトで作成しましょう。完了すれば、Host Managementで展開されるリソースとほぼ同じものが各アカウント・リージョンに展開されています。

大阪リージョンに展開できなかったリソース

ここまで「Host Managementで展開されるリソースとほぼ同じもの」という言い方をしていましたが、一部展開できなかったリソースがあったためです。

以下が元のテンプレートではエラーになりコメントアウトしたリソースです。

  SystemAssociationForEnablingExplorer:
    Type: "AWS::SSM::Association"
    Properties:
      Name: AWS-EnableExplorer
      AssociationName:
        "Fn::Join":
          - ""
          - - AWS-QuickSetup-SSMHostMgmt-EnableExplorer-
            - Ref: QSConfigurationId
      Parameters:
        AutomationAssumeRole:
          - "Fn::If":
              - IsNoAutomationAssumeRoleProvided
              - "Fn::GetAtt":
                  - RoleForAutomation
                  - Arn
              - Ref: ProvidedAssumeRoleArn
    Condition: AtLeastOneAssociationCreated

中身としてはステートマネージャーの関連付けで、AWS-EnableExplorerというAWSドキュメントを実行します。

大阪リージョンではAWS-EnableExplorerのドキュメントが存在していないためにエラーとなったようです。

ということで、組織内のSSM Explorerの有効化は別の手段で行う必要がありそうです。

(任意)Qucik SetupのHost Managementコンソールでも確認できるようにする

これはAWS側からは想定された操作ではないと思うので任意です。

StackSetsを展開しただけなので、当然Host Managementをコンソールから確認しても未設定の表示になっています。

これを表示できるようにする方法が、StackSetsにタグを設定することです。StackSetsの編集から以下をタグ付けしてみてください。

Key Value
QuickSetupID xxxx
QuickSetupType Host Management
QuickSetupVersion 3.1

更新が完了してからHost Managementをコンソールを開くと、設定の確認ボタンが表示されるようになりました。

詳細を表示すると、StackSetsで展開されている数やステータスが確認できます。

通常のHost Managementでは関連付けのステータスも確認できるのですが、おそらくExplorerを有効化できなかった影響で表示されなくなっていました。

StackSetsで確認すればいい情報ではありますが、Host Managementでも確認したい方は設定してみてもいいかもしれません。

まとめ

大阪リージョンも含めてQuick SetupのHost Managementとほぼ同様の設定を展開してみました。

いつになるかは分かりませんが大阪リージョンも対応してくれるはずなので、どうしてもHost Managementを大阪でも使いたい人は参考にしてみてください。

大阪リージョンが対応した場合は、手動作成したStackSetsを削除してHost Managementから展開しなおすだけです。それほど手間でもないので繋ぎとしても十分使えるかと思います。

参考