SSM Quick SetupのHost Managementとほぼ同じ設定を大阪リージョンにも展開する
はじめに
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から展開しなおすだけです。それほど手間でもないので繋ぎとしても十分使えるかと思います。