diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 8be7ec64..90fb7a62 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.9.1 +current_version = 1.10.0 commit = True message = Bumps version to {new_version} tag = False diff --git a/modules/lx-autoscale/main.tf b/modules/lx-autoscale/main.tf index 58d6b0b1..047bbc50 100644 --- a/modules/lx-autoscale/main.tf +++ b/modules/lx-autoscale/main.tf @@ -49,6 +49,7 @@ resource "aws_cloudformation_stack" "watchmaker-lx-autoscale" { WatchmakerOuPath = "${var.WatchmakerOuPath}" WatchmakerAdminGroups = "${var.WatchmakerAdminGroups}" WatchmakerAdminUsers = "${var.WatchmakerAdminUsers}" + WatchmakerExtraArgs = "${var.WatchmakerExtraArgs}" CfnEndpointUrl = "${var.CfnEndpointUrl}" CfnGetPipUrl = "${var.CfnGetPipUrl}" CfnBootstrapUtilsUrl = "${var.CfnBootstrapUtilsUrl}" diff --git a/modules/lx-autoscale/variables.tf b/modules/lx-autoscale/variables.tf index 90156be1..1a567b40 100644 --- a/modules/lx-autoscale/variables.tf +++ b/modules/lx-autoscale/variables.tf @@ -242,6 +242,12 @@ variable "WatchmakerAdminUsers" { default = "" } +variable "WatchmakerExtraArgs" { + type = "string" + description = "(Optional) Additional parameters to be passed to the Watchmaker CLI" + default = "" +} + variable "CloudWatchAgentUrl" { type = "string" description = "(Optional) S3 URL to CloudWatch Agent installer. Example: s3://amazoncloudwatch-agent/linux/amd64/latest/AmazonCloudWatchAgent.zip" diff --git a/modules/lx-autoscale/watchmaker-lx-autoscale.params.cfn.yaml b/modules/lx-autoscale/watchmaker-lx-autoscale.params.cfn.yaml index edd1e3b6..5bd330dd 100644 --- a/modules/lx-autoscale/watchmaker-lx-autoscale.params.cfn.yaml +++ b/modules/lx-autoscale/watchmaker-lx-autoscale.params.cfn.yaml @@ -54,6 +54,8 @@ ParameterValue: __WATCHMAKEROUPATH__ - ParameterKey: WatchmakerAdminGroups ParameterValue: __WATCHMAKERADMINGROUPS__ +- ParameterKey: WatchmakerExtraArgs + ParameterValue: __WATCHMAKEREXTRAARGS__ - ParameterKey: CloudWatchAgentUrl ParameterValue: __CWAGENTURL__ - ParameterKey: CloudWatchAppLogs diff --git a/modules/lx-autoscale/watchmaker-lx-autoscale.template.cfn.yaml b/modules/lx-autoscale/watchmaker-lx-autoscale.template.cfn.yaml index 3e37a96e..41813268 100644 --- a/modules/lx-autoscale/watchmaker-lx-autoscale.template.cfn.yaml +++ b/modules/lx-autoscale/watchmaker-lx-autoscale.template.cfn.yaml @@ -1,88 +1,88 @@ AWSTemplateFormatVersion: '2010-09-09' Conditions: - AssignInstanceRole: !Not - - !Equals + AssignInstanceRole: !Not + - !Equals - !Ref InstanceRole - '' - AssignPublicIp: !Not - - !Equals + AssignPublicIp: !Not + - !Equals - !Ref NoPublicIp - 'true' - CreateAppVolume: !Equals + CreateAppVolume: !Equals - !Ref AppVolumeDevice - 'true' CreatePatchGroupTag: !Not - !Equals - !Ref PatchGroup - '' - ExecuteAppScript: !Not - - !Equals + ExecuteAppScript: !Not + - !Equals - !Ref AppScriptUrl - '' - InstallCloudWatchAgent: !Not - - !Equals + InstallCloudWatchAgent: !Not + - !Equals - !Ref CloudWatchAgentUrl - '' - InstallUpdates: !Not - - !Equals + InstallUpdates: !Not + - !Equals - !Ref NoUpdates - 'true' - Reboot: !Not - - !Equals + Reboot: !Not + - !Equals - !Ref NoReboot - 'true' - SupportsNvme: !Equals - - !FindInMap + SupportsNvme: !Equals + - !FindInMap - InstanceTypeMap - !Ref InstanceType - SupportsNvme - 'true' - UseAdminGroups: !Not - - !Equals + UseAdminGroups: !Not + - !Equals - !Ref WatchmakerAdminGroups - '' - UseAdminUsers: !Not - - !Equals + UseAdminUsers: !Not + - !Equals - !Ref WatchmakerAdminUsers - '' - UseCfnUrl: !Not - - !Equals + UseCfnUrl: !Not + - !Equals - !Ref CfnEndpointUrl - '' - UseElbHealthCheck: !Or + UseElbHealthCheck: !Or - !Condition UseLoadBalancerNames - !Condition UseTargetGroupArns - UseEnvironment: !Not - - !Equals + UseEnvironment: !Not + - !Equals - !Ref WatchmakerEnvironment - '' - UseLoadBalancerNames: !Not + UseLoadBalancerNames: !Not - !Equals - !Join - '' - !Ref LoadBalancerNames - '' - UseOuPath: !Not - - !Equals + UseOuPath: !Not + - !Equals - !Ref WatchmakerOuPath - '' - UseScheduledAction: !And - - !Not - - !Equals + UseScheduledAction: !And + - !Not + - !Equals - !Ref ScaleUpSchedule - '' - - !Not - - !Equals + - !Not + - !Equals - !Ref ScaleDownSchedule - '' - UseTargetGroupArns: !Not + UseTargetGroupArns: !Not - !Equals - !Join - '' - !Ref TargetGroupArns - '' - UseWamConfig: !Not - - !Equals + UseWamConfig: !Not + - !Equals - !Ref WatchmakerConfig - '' Description: >- @@ -166,6 +166,7 @@ Metadata: - WatchmakerOuPath - WatchmakerAdminGroups - WatchmakerAdminUsers + - WatchmakerExtraArgs - Label: default: EC2 Application Configuration Parameters: @@ -208,7 +209,7 @@ Metadata: default: Force Cfn Init Update ToggleNewInstances: default: Force New Instances - Version: 1.9.1 + Version: 1.10.0 Outputs: ScaleDownScheduledAction: Condition: UseScheduledAction @@ -473,6 +474,12 @@ Parameters: (Optional) Colon-separated list of domain users that should have admin permissions on the EC2 instance Type: String + WatchmakerExtraArgs: + Default: '' + Description: >- + (Optional) Additional Watchmaker parameters. E.g. --exclude-states scap*scan + or --salt-states 'None' + Type: String WatchmakerConfig: AllowedPattern: '^$|^(http[s]?|s3|file)://.*$' Default: '' @@ -520,16 +527,16 @@ Resources: Timeout: PT30M Properties: DesiredCapacity: !Ref DesiredCapacity - HealthCheckGracePeriod: !If + HealthCheckGracePeriod: !If - UseElbHealthCheck - 3600 - !Ref 'AWS::NoValue' - HealthCheckType: !If + HealthCheckType: !If - UseElbHealthCheck - ELB - EC2 LaunchConfigurationName: !Ref WatchmakerLaunchConfig - LoadBalancerNames: !If + LoadBalancerNames: !If - UseLoadBalancerNames - !Ref LoadBalancerNames - !Ref 'AWS::NoValue' @@ -546,7 +553,7 @@ Resources: Value: !Ref PatchGroup PropagateAtLaunch: true - !Ref 'AWS::NoValue' - TargetGroupARNs: !If + TargetGroupARNs: !If - UseTargetGroupArns - !Ref TargetGroupArns - !Ref 'AWS::NoValue' @@ -561,35 +568,35 @@ Resources: configSets: launch: - setup - - !If + - !If - InstallCloudWatchAgent - cw-agent-install - !Ref 'AWS::NoValue' - watchmaker-install - watchmaker-launch - - !If + - !If - ExecuteAppScript - make-app - !Ref 'AWS::NoValue' - finalize - - !If + - !If - Reboot - reboot - !Ref 'AWS::NoValue' update: - setup - - !If + - !If - InstallUpdates - install-updates - !Ref 'AWS::NoValue' - watchmaker-install - watchmaker-update - - !If + - !If - ExecuteAppScript - make-app - !Ref 'AWS::NoValue' - finalize - - !If + - !If - Reboot - reboot - !Ref 'AWS::NoValue' @@ -618,25 +625,25 @@ Resources: files: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json: content: !Sub |- - { - "logs": + { + "logs": { "logs_collected": { - "files": + "files": { - "collect_list": [ + "collect_list": [ { "file_path": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log", "log_group_name": "/aws/ec2/lx/${AWS::StackName}", "log_stream_name": "cloudwatch_agent_logs_{instance_id}", - "timestamp_format": "%H:%M:%S %y %b %-d" + "timestamp_format": "%H:%M:%S %y %b %-d" }, { "file_path": "/var/log/cfn-init.log", "log_group_name": "/aws/ec2/lx/${AWS::StackName}", "log_stream_name": "cfn_init_logs_{instance_id}", - "timestamp_format": "%H:%M:%S %y %b %-d" + "timestamp_format": "%H:%M:%S %y %b %-d" }, { "file_path": "/var/log/messages", @@ -667,7 +674,7 @@ Resources: - |- import json import os - + cloudwatch_baseline = "/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json" log_group_name = "/aws/ec2/lx/${AWS::StackName}" log_paths_input = (r'''${local_addCWLtarget}''').split(",") @@ -710,9 +717,9 @@ Resources: command: !Sub - >- cfn-signal -e 0 --stack ${AWS::StackName} --resource WatchmakerAutoScalingGroup --region ${AWS::Region} - ${local_AssignInstanceRole} + ${local_AssignInstanceRole} ${local_UseCfnUrl} - - + - local_AssignInstanceRole: !If [AssignInstanceRole, !Sub '--role ${InstanceRole}', ''] local_UseCfnUrl: !If [UseCfnUrl, !Sub '--url ${CfnEndpointUrl}', ''] ignoreErrors: 'true' @@ -723,7 +730,7 @@ Resources: make-app: commands: 05-get-appscript: - command: + command: !Sub >- mkdir -p /etc/cfn/scripts && aws s3 cp ${AppScriptUrl} @@ -748,21 +755,21 @@ Resources: ${local_UseCfnUrl} interval=1 verbose=true - - + - local_AssignInstanceRole: !If [AssignInstanceRole, !Sub 'role=${InstanceRole}', ''] local_UseCfnUrl: !If [UseCfnUrl, !Sub 'url=${CfnEndpointUrl}', ''] group: root mode: '000400' owner: root /etc/cfn/hooks.d/cfn-auto-reloader.conf: - content: !Sub + content: !Sub - |- [cfn-auto-reloader-hook] triggers=post.update path=Resources.WatchmakerInstance.Metadata action=cfn-init -v -c update --stack ${AWS::StackName} --resource WatchmakerLaunchConfig --region ${AWS::Region} ${local_AssignInstanceRole} ${local_UseCfnUrl} runas=root - - + - local_AssignInstanceRole: !If [AssignInstanceRole, !Sub '--role ${InstanceRole}', ''] local_UseCfnUrl: !If [UseCfnUrl, !Sub '--url ${CfnEndpointUrl}', ''] group: root @@ -806,6 +813,7 @@ Resources: ${local_UseOUPath} ${local_UseAdminGroups} ${local_UseAdminUsers} + ${WatchmakerExtraArgs} - local_UseWamConfig: !If [UseWamConfig, !Sub '--config ${WatchmakerConfig}', ''] local_UseEnvironment: !If [UseEnvironment, !Sub '--env ${WatchmakerEnvironment}', ''] @@ -823,6 +831,7 @@ Resources: ${local_UseOUPath} ${local_UseAdminGroups} ${local_UseAdminUsers} + ${WatchmakerExtraArgs} - local_UseWamConfig: !If [UseWamConfig, !Sub '--config ${WatchmakerConfig}', ''] local_UseEnvironment: !If [UseEnvironment, !Sub '--env ${WatchmakerEnvironment}', ''] @@ -831,18 +840,18 @@ Resources: local_UseAdminUsers: !If [UseAdminUsers, !Sub '--admin-users ${WatchmakerAdminUsers}', ''] ToggleCfnInitUpdate: !Ref ToggleCfnInitUpdate Properties: - AssociatePublicIpAddress: !If + AssociatePublicIpAddress: !If - AssignPublicIp - true - false BlockDeviceMappings: - - DeviceName: !Sub + - DeviceName: !Sub - '/dev/${local_Distro2RootDevice}' - local_Distro2RootDevice: !FindInMap [Distro2RootDevice, !Ref AmiDistro, DeviceName] Ebs: DeleteOnTermination: true VolumeType: gp2 - - !If + - !If - CreateAppVolume - DeviceName: /dev/xvdf Ebs: @@ -850,7 +859,7 @@ Resources: VolumeSize: !Ref AppVolumeSize VolumeType: !Ref AppVolumeType - !Ref 'AWS::NoValue' - IamInstanceProfile: !If + IamInstanceProfile: !If - AssignInstanceRole - !Ref InstanceRole - !Ref 'AWS::NoValue' @@ -858,7 +867,7 @@ Resources: InstanceType: !Ref InstanceType KeyName: !Ref KeyPairName SecurityGroups: !Ref SecurityGroupIds - UserData: + UserData: !Base64 Fn::Sub: - | @@ -938,14 +947,14 @@ Resources: ( echo 'ERROR: cfn-init failed! Aborting!'; cfn-signal -e 1 --stack ${AWS::StackName} --resource WatchmakerAutoScalingGroup --region ${AWS::Region} \ ${local_AssignInstanceRole} ${local_UseCfnUrl}; exit 1) --===============3585321300151562773==-- - - - local_CreateAppVolume: !If + - + local_CreateAppVolume: !If - CreateAppVolume - !Sub - |+ bootcmd: - cloud-init-per instance mkfsappvolume mkfs -t ext4 ${local_SupportsNvme} - mounts: + mounts: - [${local_SupportsNvme}, ${AppVolumeMountPath}] - local_SupportsNvme: !If [SupportsNvme, /dev/nvme1n1, /dev/xvdf] - '' diff --git a/modules/lx-instance/main.tf b/modules/lx-instance/main.tf index 02af9269..93f27253 100644 --- a/modules/lx-instance/main.tf +++ b/modules/lx-instance/main.tf @@ -44,6 +44,7 @@ resource "aws_cloudformation_stack" "watchmaker-lx-instance" { WatchmakerComputerName = "${var.WatchmakerComputerName}" WatchmakerAdminGroups = "${var.WatchmakerAdminGroups}" WatchmakerAdminUsers = "${var.WatchmakerAdminUsers}" + WatchmakerExtraArgs = "${var.WatchmakerExtraArgs}" CfnEndpointUrl = "${var.CfnEndpointUrl}" CfnGetPipUrl = "${var.CfnGetPipUrl}" CfnBootstrapUtilsUrl = "${var.CfnBootstrapUtilsUrl}" diff --git a/modules/lx-instance/variables.tf b/modules/lx-instance/variables.tf index c53e2c8e..72e450ab 100644 --- a/modules/lx-instance/variables.tf +++ b/modules/lx-instance/variables.tf @@ -212,6 +212,12 @@ variable "WatchmakerAdminUsers" { default = "" } +variable "WatchmakerExtraArgs" { + type = "string" + description = "(Optional) Additional parameters to be passed to the Watchmaker CLI" + default = "" +} + variable "CloudWatchAgentUrl" { type = "string" description = "(Optional) S3 URL to CloudWatch Agent installer. Example: s3://amazoncloudwatch-agent/linux/amd64/latest/AmazonCloudWatchAgent.zip" diff --git a/modules/lx-instance/watchmaker-lx-instance.params.cfn.yaml b/modules/lx-instance/watchmaker-lx-instance.params.cfn.yaml index b795e4b4..875572b8 100644 --- a/modules/lx-instance/watchmaker-lx-instance.params.cfn.yaml +++ b/modules/lx-instance/watchmaker-lx-instance.params.cfn.yaml @@ -42,6 +42,8 @@ ParameterValue: __WATCHMAKERADMINGROUPS__ - ParameterKey: WatchmakerAdminUsers ParameterValue: __WATCHMAKERADMINUSERS__ +- ParameterKey: WatchmakerExtraArgs + ParameterValue: __WATCHMAKEREXTRAARGS__ - ParameterKey: WatchmakerComputerName ParameterValue: __COMPUTERNAME__ - ParameterKey: WatchmakerConfig diff --git a/modules/lx-instance/watchmaker-lx-instance.template.cfn.yaml b/modules/lx-instance/watchmaker-lx-instance.template.cfn.yaml index 73b613b9..ea1ccb72 100644 --- a/modules/lx-instance/watchmaker-lx-instance.template.cfn.yaml +++ b/modules/lx-instance/watchmaker-lx-instance.template.cfn.yaml @@ -1,72 +1,72 @@ AWSTemplateFormatVersion: '2010-09-09' Conditions: - AssignInstanceRole: !Not - - !Equals + AssignInstanceRole: !Not + - !Equals - !Ref InstanceRole - '' - AssignPublicIp: !Not - - !Equals + AssignPublicIp: !Not + - !Equals - !Ref NoPublicIp - 'true' - AssignStaticPrivateIp: !Not - - !Equals + AssignStaticPrivateIp: !Not + - !Equals - !Ref PrivateIp - '' - CreateAppVolume: !Equals + CreateAppVolume: !Equals - !Ref AppVolumeDevice - 'true' CreatePatchGroupTag: !Not - !Equals - !Ref PatchGroup - '' - ExecuteAppScript: !Not - - !Equals + ExecuteAppScript: !Not + - !Equals - !Ref AppScriptUrl - '' - InstallCloudWatchAgent: !Not - - !Equals + InstallCloudWatchAgent: !Not + - !Equals - !Ref CloudWatchAgentUrl - '' - InstallUpdates: !Not - - !Equals + InstallUpdates: !Not + - !Equals - !Ref NoUpdates - 'true' - Reboot: !Not - - !Equals + Reboot: !Not + - !Equals - !Ref NoReboot - 'true' - SupportsNvme: !Equals - - !FindInMap + SupportsNvme: !Equals + - !FindInMap - InstanceTypeMap - !Ref InstanceType - SupportsNvme - 'true' - UseAdminGroups: !Not - - !Equals + UseAdminGroups: !Not + - !Equals - !Ref WatchmakerAdminGroups - '' - UseAdminUsers: !Not - - !Equals + UseAdminUsers: !Not + - !Equals - !Ref WatchmakerAdminUsers - '' - UseCfnUrl: !Not - - !Equals + UseCfnUrl: !Not + - !Equals - !Ref CfnEndpointUrl - '' - UseComputerName: !Not - - !Equals + UseComputerName: !Not + - !Equals - !Ref WatchmakerComputerName - '' - UseEnvironment: !Not - - !Equals + UseEnvironment: !Not + - !Equals - !Ref WatchmakerEnvironment - '' - UseOuPath: !Not - - !Equals + UseOuPath: !Not + - !Equals - !Ref WatchmakerOuPath - '' - UseWamConfig: !Not - - !Equals + UseWamConfig: !Not + - !Equals - !Ref WatchmakerConfig - '' Description: >- @@ -151,6 +151,7 @@ Metadata: - WatchmakerComputerName - WatchmakerAdminGroups - WatchmakerAdminUsers + - WatchmakerExtraArgs - Label: default: EC2 Application Configuration Parameters: @@ -181,7 +182,7 @@ Metadata: ParameterLabels: ToggleCfnInitUpdate: default: Force Cfn Init Update - Version: 1.9.1 + Version: 1.10.0 Outputs: WatchmakerInstanceId: Description: Instance ID @@ -396,6 +397,12 @@ Parameters: (Optional) Colon-separated list of domain users that should have admin permissions on the EC2 instance Type: String + WatchmakerExtraArgs: + Default: '' + Description: >- + (Optional) Additional Watchmaker parameters. E.g. --exclude-states scap*scan + or --salt-states 'None' + Type: String WatchmakerComputerName: Default: '' Description: (Optional) Sets the hostname/computername within the OS @@ -436,35 +443,35 @@ Resources: configSets: launch: - setup - - !If + - !If - InstallCloudWatchAgent - cw-agent-install - !Ref 'AWS::NoValue' - watchmaker-install - watchmaker-launch - - !If + - !If - ExecuteAppScript - make-app - !Ref 'AWS::NoValue' - finalize - - !If + - !If - Reboot - reboot - !Ref 'AWS::NoValue' update: - setup - - !If + - !If - InstallUpdates - install-updates - !Ref 'AWS::NoValue' - watchmaker-install - watchmaker-update - - !If + - !If - ExecuteAppScript - make-app - !Ref 'AWS::NoValue' - finalize - - !If + - !If - Reboot - reboot - !Ref 'AWS::NoValue' @@ -493,25 +500,25 @@ Resources: files: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json: content: !Sub |- - { - "logs": + { + "logs": { "logs_collected": { - "files": + "files": { - "collect_list": [ + "collect_list": [ { "file_path": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log", "log_group_name": "/aws/ec2/lx/${AWS::StackName}", "log_stream_name": "cloudwatch_agent_logs_{instance_id}", - "timestamp_format": "%H:%M:%S %y %b %-d" + "timestamp_format": "%H:%M:%S %y %b %-d" }, { "file_path": "/var/log/cfn-init.log", "log_group_name": "/aws/ec2/lx/${AWS::StackName}", "log_stream_name": "cfn_init_logs_{instance_id}", - "timestamp_format": "%H:%M:%S %y %b %-d" + "timestamp_format": "%H:%M:%S %y %b %-d" }, { "file_path": "/var/log/messages", @@ -542,7 +549,7 @@ Resources: - |- import json import os - + cloudwatch_baseline = "/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json" log_group_name = "/aws/ec2/lx/${AWS::StackName}" log_paths_input = (r'''${local_addCWLtarget}''').split(",") @@ -585,9 +592,9 @@ Resources: command: !Sub - >- cfn-signal -e 0 --stack ${AWS::StackName} --resource WatchmakerInstance --region ${AWS::Region} - ${local_AssignInstanceRole} + ${local_AssignInstanceRole} ${local_UseCfnUrl} - - + - local_AssignInstanceRole: !If [AssignInstanceRole, !Sub '--role ${InstanceRole}', ''] local_UseCfnUrl: !If [UseCfnUrl, !Sub '--url ${CfnEndpointUrl}', ''] ignoreErrors: 'true' @@ -598,7 +605,7 @@ Resources: make-app: commands: 05-get-appscript: - command: + command: !Sub >- mkdir -p /etc/cfn/scripts && aws s3 cp ${AppScriptUrl} @@ -623,21 +630,21 @@ Resources: ${local_UseCfnUrl} interval=1 verbose=true - - + - local_AssignInstanceRole: !If [AssignInstanceRole, !Sub 'role=${InstanceRole}', ''] local_UseCfnUrl: !If [UseCfnUrl, !Sub 'url=${CfnEndpointUrl}', ''] group: root mode: '000400' owner: root /etc/cfn/hooks.d/cfn-auto-reloader.conf: - content: !Sub + content: !Sub - |- [cfn-auto-reloader-hook] triggers=post.update path=Resources.WatchmakerInstance.Metadata action=cfn-init -v -c update --stack ${AWS::StackName} --resource WatchmakerInstance --region ${AWS::Region} ${local_AssignInstanceRole} ${local_UseCfnUrl} runas=root - - + - local_AssignInstanceRole: !If [AssignInstanceRole, !Sub '--role ${InstanceRole}', ''] local_UseCfnUrl: !If [UseCfnUrl, !Sub '--url ${CfnEndpointUrl}', ''] group: root @@ -682,6 +689,7 @@ Resources: ${local_UseComputerName} ${local_UseAdminGroups} ${local_UseAdminUsers} + ${WatchmakerExtraArgs} - local_UseWamConfig: !If [UseWamConfig, !Sub '--config ${WatchmakerConfig}', ''] local_UseEnvironment: !If [UseEnvironment, !Sub '--env ${WatchmakerEnvironment}', ''] @@ -701,6 +709,7 @@ Resources: ${local_UseComputerName} ${local_UseAdminGroups} ${local_UseAdminUsers} + ${WatchmakerExtraArgs} - local_UseWamConfig: !If [UseWamConfig, !Sub '--config ${WatchmakerConfig}', ''] local_UseEnvironment: !If [UseEnvironment, !Sub '--env ${WatchmakerEnvironment}', ''] @@ -711,13 +720,13 @@ Resources: ToggleCfnInitUpdate: !Ref ToggleCfnInitUpdate Properties: BlockDeviceMappings: - - DeviceName: !Sub + - DeviceName: !Sub - '/dev/${local_Distro2RootDevice}' - local_Distro2RootDevice: !FindInMap [Distro2RootDevice, !Ref AmiDistro, DeviceName] Ebs: DeleteOnTermination: true VolumeType: gp2 - - !If + - !If - CreateAppVolume - DeviceName: /dev/xvdf Ebs: @@ -725,7 +734,7 @@ Resources: VolumeSize: !Ref AppVolumeSize VolumeType: !Ref AppVolumeType - !Ref 'AWS::NoValue' - IamInstanceProfile: !If + IamInstanceProfile: !If - AssignInstanceRole - !Ref InstanceRole - !Ref 'AWS::NoValue' @@ -733,13 +742,13 @@ Resources: InstanceType: !Ref InstanceType KeyName: !Ref KeyPairName NetworkInterfaces: - - AssociatePublicIpAddress: !If + - AssociatePublicIpAddress: !If - AssignPublicIp - true - false DeviceIndex: '0' GroupSet: !Ref SecurityGroupIds - PrivateIpAddress: !If + PrivateIpAddress: !If - AssignStaticPrivateIp - !Ref PrivateIp - !Ref 'AWS::NoValue' @@ -753,7 +762,7 @@ Resources: Key: Patch Group Value: !Ref PatchGroup - !Ref 'AWS::NoValue' - UserData: + UserData: !Base64 Fn::Sub: - | @@ -789,7 +798,7 @@ Resources: # Get pip PYPI_URL=${PypiIndexUrl} curl --silent --show-error --retry 5 -L ${CfnGetPipUrl} | python3 - --index-url="$PYPI_URL" - + # Add pip to path hash pip 2> /dev/null || PATH="${!PATH}:/usr/local/bin" @@ -830,14 +839,14 @@ Resources: ( echo 'ERROR: cfn-init failed! Aborting!'; cfn-signal -e 1 --stack ${AWS::StackName} --resource WatchmakerInstance --region ${AWS::Region} \ ${local_AssignInstanceRole} ${local_UseCfnUrl}; exit 1) --===============3585321300151562773==-- - - - local_CreateAppVolume: !If + - + local_CreateAppVolume: !If - CreateAppVolume - !Sub - |+ bootcmd: - cloud-init-per instance mkfsappvolume mkfs -t ext4 ${local_SupportsNvme} - mounts: + mounts: - [${local_SupportsNvme}, ${AppVolumeMountPath}] - local_SupportsNvme: !If [SupportsNvme, /dev/nvme1n1, /dev/xvdf] - '' diff --git a/modules/win-autoscale/main.tf b/modules/win-autoscale/main.tf index a33183f2..ea487705 100644 --- a/modules/win-autoscale/main.tf +++ b/modules/win-autoscale/main.tf @@ -46,6 +46,7 @@ resource "aws_cloudformation_stack" "watchmaker-win-autoscale" { WatchmakerEnvironment = "${var.WatchmakerEnvironment}" WatchmakerOuPath = "${var.WatchmakerOuPath}" WatchmakerAdminGroups = "${var.WatchmakerAdminGroups}" + WatchmakerExtraArgs = "${var.WatchmakerExtraArgs}" CfnEndpointUrl = "${var.CfnEndpointUrl}" ToggleCfnInitUpdate = "${var.ToggleCfnInitUpdate}" ToggleNewInstances = "${var.ToggleNewInstances}" diff --git a/modules/win-autoscale/variables.tf b/modules/win-autoscale/variables.tf index 718ac991..27fd9e0b 100644 --- a/modules/win-autoscale/variables.tf +++ b/modules/win-autoscale/variables.tf @@ -223,6 +223,12 @@ variable "WatchmakerAdminGroups" { default = "" } +variable "WatchmakerExtraArgs" { + type = "string" + description = "(Optional) Additional parameters to be passed to the Watchmaker CLI" + default = "" +} + variable "CloudWatchAgentUrl" { type = "string" description = "(Optional) S3 URL to CloudWatch Agent installer. Example: s3://amazoncloudwatch-agent/windows/amd64/latest/AmazonCloudWatchAgent.zip" diff --git a/modules/win-autoscale/watchmaker-win-autoscale.params.cfn.yaml b/modules/win-autoscale/watchmaker-win-autoscale.params.cfn.yaml index 6d0f310d..b50afbcf 100644 --- a/modules/win-autoscale/watchmaker-win-autoscale.params.cfn.yaml +++ b/modules/win-autoscale/watchmaker-win-autoscale.params.cfn.yaml @@ -44,6 +44,8 @@ ParameterValue: __PYTHONINSTALLER__ - ParameterKey: WatchmakerAdminGroups ParameterValue: __WATCHMAKERADMINGROUPS__ +- ParameterKey: WatchmakerExtraArgs + ParameterValue: __WATCHMAKEREXTRAARGS__ - ParameterKey: WatchmakerBootstrapper ParameterValue: __WATCHMAKERBOOTSTRAPPER__ - ParameterKey: WatchmakerConfig diff --git a/modules/win-autoscale/watchmaker-win-autoscale.template.cfn.yaml b/modules/win-autoscale/watchmaker-win-autoscale.template.cfn.yaml index e7ddab04..6ddeb572 100644 --- a/modules/win-autoscale/watchmaker-win-autoscale.template.cfn.yaml +++ b/modules/win-autoscale/watchmaker-win-autoscale.template.cfn.yaml @@ -1,75 +1,75 @@ AWSTemplateFormatVersion: '2010-09-09' Conditions: - AssignInstanceRole: !Not - - !Equals + AssignInstanceRole: !Not + - !Equals - !Ref InstanceRole - '' - AssignPublicIp: !Not - - !Equals + AssignPublicIp: !Not + - !Equals - !Ref NoPublicIp - 'true' - CreateAppVolume: !Not - - !Equals + CreateAppVolume: !Not + - !Equals - !Ref AppVolumeDevice - '' CreatePatchGroupTag: !Not - !Equals - !Ref PatchGroup - '' - ExecuteAppScript: !Not - - !Equals + ExecuteAppScript: !Not + - !Equals - !Ref AppScriptUrl - '' - InstallCloudWatchAgent: !Not - - !Equals + InstallCloudWatchAgent: !Not + - !Equals - !Ref CloudWatchAgentUrl - '' - Reboot: !Not - - !Equals + Reboot: !Not + - !Equals - !Ref NoReboot - 'true' - UseAdminGroups: !Not - - !Equals + UseAdminGroups: !Not + - !Equals - !Ref WatchmakerAdminGroups - '' - UseCfnUrl: !Not - - !Equals + UseCfnUrl: !Not + - !Equals - !Ref CfnEndpointUrl - '' - UseElbHealthCheck: !Or + UseElbHealthCheck: !Or - !Condition UseLoadBalancerNames - !Condition UseTargetGroupArns - UseEnvironment: !Not - - !Equals + UseEnvironment: !Not + - !Equals - !Ref WatchmakerEnvironment - '' - UseLoadBalancerNames: !Not + UseLoadBalancerNames: !Not - !Equals - - !Join + - !Join - '' - !Ref LoadBalancerNames - '' - UseOuPath: !Not - - !Equals + UseOuPath: !Not + - !Equals - !Ref WatchmakerOuPath - '' - UseScheduledAction: !And - - !Not - - !Equals + UseScheduledAction: !And + - !Not + - !Equals - !Ref ScaleUpSchedule - '' - - !Not - - !Equals + - !Not + - !Equals - !Ref ScaleDownSchedule - '' - UseTargetGroupArns: !Not - - !Equals - - !Join + UseTargetGroupArns: !Not + - !Equals + - !Join - '' - !Ref TargetGroupArns - '' - UseWamConfig: !Not - - !Equals + UseWamConfig: !Not + - !Equals - !Ref WatchmakerConfig - '' Description: >- @@ -82,7 +82,7 @@ Mappings: powershell: command: >- powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy - Bypass + Bypass Metadata: 'AWS::CloudFormation::Interface': ParameterGroups: @@ -107,6 +107,7 @@ Metadata: - WatchmakerEnvironment - WatchmakerOuPath - WatchmakerAdminGroups + - WatchmakerExtraArgs - Label: default: EC2 Application Configuration Parameters: @@ -145,7 +146,7 @@ Metadata: default: Force Cfn Init Update ToggleNewInstances: default: Force New Instances - Version: 1.9.1 + Version: 1.10.0 Outputs: ScaleDownScheduledAction: Condition: UseScheduledAction @@ -372,6 +373,12 @@ Parameters: (Optional) Colon-separated list of domain groups that should have admin permissions on the EC2 instance Type: String + WatchmakerExtraArgs: + Default: '' + Description: >- + (Optional) Additional Watchmaker parameters. E.g. --exclude-states scap*scan + or --salt-states 'None' + Type: String WatchmakerBootstrapper: AllowedPattern: '^$|^http[s]?://.*\.ps1$' Default: >- @@ -425,16 +432,16 @@ Resources: Timeout: PT60M Properties: DesiredCapacity: !Ref DesiredCapacity - HealthCheckGracePeriod: !If + HealthCheckGracePeriod: !If - UseElbHealthCheck - 3600 - !Ref 'AWS::NoValue' - HealthCheckType: !If + HealthCheckType: !If - UseElbHealthCheck - ELB - EC2 LaunchConfigurationName: !Ref WatchmakerLaunchConfig - LoadBalancerNames: !If + LoadBalancerNames: !If - UseLoadBalancerNames - !Ref LoadBalancerNames - !Ref 'AWS::NoValue' @@ -451,7 +458,7 @@ Resources: Value: !Ref PatchGroup PropagateAtLaunch: true - !Ref 'AWS::NoValue' - TargetGroupARNs: !If + TargetGroupARNs: !If - UseTargetGroupArns - !Ref TargetGroupArns - !Ref 'AWS::NoValue' @@ -469,16 +476,16 @@ Resources: - make-app launch: - setup - - !If + - !If - InstallCloudWatchAgent - install-cloudwatch-agent - !Ref 'AWS::NoValue' - watchmaker-launch - - !If + - !If - ExecuteAppScript - ConfigSet: appscript - !Ref 'AWS::NoValue' - - !If + - !If - Reboot - reboot - !Ref 'AWS::NoValue' @@ -486,11 +493,11 @@ Resources: update: - setup - watchmaker-update - - !If + - !If - ExecuteAppScript - ConfigSet: appscript - !Ref 'AWS::NoValue' - - !If + - !If - Reboot - reboot - !Ref 'AWS::NoValue' @@ -532,7 +539,7 @@ Resources: Read-S3Object -BucketName $CloudWatchAgentUri.Host ` -Key ($CloudWatchAgentUri.Segments[1..($CloudWatchAgentUri.Segments.Length-1)] -Join '') ` -File $CloudWatchAgentZipFile ` - -Region ${AWS::Region}; + -Region ${AWS::Region}; $CloudWatchAgentInstallScript = $CloudWatchAgentScriptDir + '\install.ps1'; $CloudWatchAgentConfig = $CloudWatchAgentScriptDir + '\aws-cloudwatch-agent-config.json'; if ($PSVersionTable.PSVersion.Major -ge 5) { Expand-Archive -Path $CloudWatchAgentZipFile -DestinationPath $CloudWatchAgentScriptDir; @@ -547,7 +554,7 @@ Resources: .\amazon-cloudwatch-agent-ctl.ps1 -a fetch-config -m ec2 -c file:$CloudWatchAgentConfig -s; Pop-Location;} -Verbose -ErrorAction Stop " - - local_ShellCommandMap: !FindInMap [ShellCommandMap, powershell, command] + local_ShellCommandMap: !FindInMap [ShellCommandMap, powershell, command] waitAfterCompletion: '0' files: 'c:\cfn\scripts\AmazonCloudWatchAgent\aws-cloudwatch-agent-config.json': @@ -588,7 +595,7 @@ Resources: } } 'c:\cfn\scripts\AmazonCloudWatchAgent\cloudwatch-applog-config.py': - content: !Sub + content: !Sub - |- import json import os @@ -613,7 +620,7 @@ Resources: print('Writing new cwl baseline') with open(cloudwatch_baseline, 'w') as f: f.write(json.dumps(baseline, sort_keys=True, indent=4)) - + if log_paths_input: print('Additional cwl paths were defined.') @@ -628,7 +635,7 @@ Resources: write_baseline(baseline) print('CWL baseline modification complete') # convert CommanDelimitedList to a string for Fn::Sub compatibility - - + - local_addCWLtarget: !Join ["," ,!Ref CloudWatchAppLogs] make-app: commands: @@ -649,7 +656,7 @@ Resources: & $AppScript ${AppScriptParams}; } -Verbose -ErrorAction Stop" - - local_ShellCommandMap: !FindInMap [ShellCommandMap, powershell, command] + local_ShellCommandMap: !FindInMap [ShellCommandMap, powershell, command] waitAfterCompletion: '0' reboot: commands: @@ -660,13 +667,13 @@ Resources: commands: 01-install-python-and-wam: command: !Sub - - >- + - >- ${local_ShellCommandMap} -Command "Invoke-Command -ScriptBlock { $ErrorActionPreference = 'Stop'; c:\cfn\scripts\watchmaker-install.ps1; } -Verbose -ErrorAction Stop" - local_ShellCommandMap: !FindInMap [ShellCommandMap, powershell, command] 10-initialize-disks: - command: !If + command: !If - CreateAppVolume - !Sub - >- @@ -674,7 +681,7 @@ Resources: $ErrorActionPreference = 'Stop'; $EC2LaunchInitDiskScript = ${!Env:ProgramData} + '\Amazon\EC2-Windows\Launch\Scripts\InitializeDisks.ps1'; $EC2LaunchInitDiskConfig = ${!Env:ProgramData} + '\Amazon\EC2-Windows\Launch\Config\DriveLetterMappingConfig.json'; - if (Test-Path $EC2LaunchInitDiskScript) {if (Test-Path $EC2LaunchInitDiskConfig) {iex $EC2LaunchInitDiskScript;} } } + if (Test-Path $EC2LaunchInitDiskScript) {if (Test-Path $EC2LaunchInitDiskConfig) {iex $EC2LaunchInitDiskScript;} } } -Verbose -ErrorAction Stop" - local_ShellCommandMap: !FindInMap [ShellCommandMap, powershell, command] @@ -701,7 +708,7 @@ Resources: triggers=post.update path=Resources.WatchmakerLaunchConfig.Metadata action=cfn-init.exe -v -c update --stack ${AWS::StackName} --resource WatchmakerLaunchConfig --region ${AWS::Region} ${local_AssignInstanceRole} ${local_UseCfnUrl} - - + - local_AssignInstanceRole: !If [AssignInstanceRole, !Sub '--role ${InstanceRole}',''] local_UseCfnUrl: !If [UseCfnUrl, !Sub '--url ${CfnEndpointUrl}', ''] 'c:\cfn\scripts\watchmaker-install.ps1': @@ -712,7 +719,7 @@ Resources: # Get the host $PypiHost="$(([System.Uri]$PypiUrl).Host)" - + # Download bootstrap file $BootstrapFile = "${!Env:Temp}\$(${!BootstrapUrl}.split('/')[-1])" (New-Object System.Net.WebClient).DownloadFile("$BootstrapUrl", "$BootstrapFile") @@ -749,17 +756,18 @@ Resources: watchmaker-launch: commands: 10-watchmaker-launch: - command: !Sub + command: !Sub - >- ${local_ShellCommandMap} -Command "Invoke-Command -ScriptBlock { $ErrorActionPreference = 'Stop'; - c:\cfn\scripts\update-path.ps1 -ErrorAction Stop -Verbose; + c:\cfn\scripts\update-path.ps1 -ErrorAction Stop -Verbose; watchmaker --log-level debug --log-dir C:\Watchmaker\Logs --no-reboot ${local_UseWamConfig} ${local_UseEnvironment} ${local_UseOuPath} ${local_UseAdminGroups} - if (-not $?) { throw 'watchmaker execution failed!' } + ${WatchmakerExtraArgs}; + if (-not $?) { throw 'watchmaker execution failed!' } } -Verbose -ErrorAction Stop" - local_ShellCommandMap: !FindInMap [ShellCommandMap, powershell, command] @@ -771,16 +779,17 @@ Resources: watchmaker-update: commands: 10-watchmaker-update: - command: !Sub + command: !Sub - >- ${local_ShellCommandMap} -Command "Invoke-Command -ScriptBlock { $ErrorActionPreference = 'Stop'; - c:\cfn\scripts\update-path.ps1 -ErrorAction Stop -Verbose; + c:\cfn\scripts\update-path.ps1 -ErrorAction Stop -Verbose; watchmaker --log-level debug --log-dir C:\Watchmaker\Logs --no-reboot --salt-states None ${local_UseWamConfig} ${local_UseEnvironment} ${local_UseOuPath} ${local_UseAdminGroups} + ${WatchmakerExtraArgs}; if (-not $?) { throw 'watchmaker execution failed!' } } -Verbose -ErrorAction Stop" - @@ -792,7 +801,7 @@ Resources: waitAfterCompletion: '0' ToggleCfnInitUpdate: !Ref ToggleCfnInitUpdate Properties: - AssociatePublicIpAddress: !If + AssociatePublicIpAddress: !If - AssignPublicIp - true - false @@ -801,7 +810,7 @@ Resources: Ebs: DeleteOnTermination: true VolumeType: gp2 - - !If + - !If - CreateAppVolume - DeviceName: !Ref AppVolumeDevice Ebs: @@ -809,7 +818,7 @@ Resources: VolumeSize: !Ref AppVolumeSize VolumeType: !Ref AppVolumeType - !Ref 'AWS::NoValue' - IamInstanceProfile: !If + IamInstanceProfile: !If - AssignInstanceRole - !Ref InstanceRole - !Ref 'AWS::NoValue' @@ -818,7 +827,7 @@ Resources: KeyName: !Ref KeyPairName SecurityGroups: !Ref SecurityGroupIds UserData: - !Base64 + !Base64 Fn::Sub: - |