はじめに
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から展開しなおすだけです。それほど手間でもないので繋ぎとしても十分使えるかと思います。