From 86cef5851fa8720d557f125acd8dad43d48d4057 Mon Sep 17 00:00:00 2001 From: Long C Lam <31355535+eemperor@users.noreply.github.com> Date: Thu, 22 Mar 2018 11:04:01 -0400 Subject: [PATCH 1/2] Added CloudWatch Logs option to Linux templates --- modules/lx-autoscale/main.tf | 1 + modules/lx-autoscale/variables.tf | 6 + .../watchmaker-lx-autoscale.cfn.json | 212 +++++++++++++++++ .../watchmaker-lx-autoscale.params.cfn.json | 4 + modules/lx-instance/main.tf | 1 + modules/lx-instance/variables.tf | 6 + .../watchmaker-lx-instance.cfn.json | 219 ++++++++++++++++++ .../watchmaker-lx-instance.params.cfn.json | 4 + 8 files changed, 453 insertions(+) diff --git a/modules/lx-autoscale/main.tf b/modules/lx-autoscale/main.tf index a4736985..3cb1e249 100644 --- a/modules/lx-autoscale/main.tf +++ b/modules/lx-autoscale/main.tf @@ -14,6 +14,7 @@ resource "aws_cloudformation_stack" "watchmaker-lx-autoscale" { AppVolumeMountPath = "${var.AppVolumeMountPath}" AppVolumeType = "${var.AppVolumeType}" AppVolumeSize = "${var.AppVolumeSize}" + CloudWatchAgentUrl = "${var.CloudWatchAgentUrl}" KeyPairName = "${var.KeyPairName}" InstanceType = "${var.InstanceType}" InstanceRole = "${var.InstanceRole}" diff --git a/modules/lx-autoscale/variables.tf b/modules/lx-autoscale/variables.tf index f23f8331..16498657 100644 --- a/modules/lx-autoscale/variables.tf +++ b/modules/lx-autoscale/variables.tf @@ -158,6 +158,12 @@ variable "WatchmakerAdminUsers" { default = "" } +variable "CloudWatchAgentUrl" { + type = "string" + description = "(Optional) S3 URL to CloudWatch Agent installer. Example: s3://amazoncloudwatch-agent/linux/amd64/latest/AmazonCloudWatchAgent.zip" + default = "" +} + variable "CfnEndpointUrl" { type = "string" description = "(Optional) URL to the CloudFormation Endpoint. e.g. https://cloudformation.us-east-1.amazonaws.com" diff --git a/modules/lx-autoscale/watchmaker-lx-autoscale.cfn.json b/modules/lx-autoscale/watchmaker-lx-autoscale.cfn.json index 0791baac..c25a718e 100644 --- a/modules/lx-autoscale/watchmaker-lx-autoscale.cfn.json +++ b/modules/lx-autoscale/watchmaker-lx-autoscale.cfn.json @@ -45,6 +45,18 @@ } ] }, + "InstallCloudWatchAgent": { + "Fn::Not": [ + { + "Fn::Equals": [ + { + "Ref": "CloudWatchAgentUrl" + }, + "" + ] + } + ] + }, "InstallUpdates": { "Fn::Not": [ { @@ -290,6 +302,7 @@ "CfnEndpointUrl", "CfnGetPipUrl", "CfnBootstrapUtilsUrl", + "CloudWatchAgentUrl", "ToggleCfnInitUpdate", "ToggleNewInstances" ] @@ -393,6 +406,12 @@ "Description": "URL to get-pip.py", "Type": "String" }, + "CloudWatchAgentUrl": { + "AllowedPattern": "^$|^s3://.*$", + "Default": "", + "Description": "(Optional) S3 URL to CloudWatch Agent installer. Example: s3://amazoncloudwatch-agent/linux/amd64/latest/AmazonCloudWatchAgent.zip", + "Type": "String" + }, "DesiredCapacity": { "Default": "1", "Description": "Desired number of instances in the Autoscaling Group", @@ -589,6 +608,15 @@ "configSets": { "launch": [ "setup", + { + "Fn::If": [ + "InstallCloudWatchAgent", + "install-cloudwatch-agent", + { + "Ref": "AWS::NoValue" + } + ] + }, "watchmaker-install", "watchmaker-launch", { @@ -704,6 +732,173 @@ } } }, + "install-cloudwatch-agent": { + "commands": { + "01-get-cloudwatch-agent": { + "command": { + "Fn::Join": [ + "", + [ + "mkdir -p /etc/cfn/scripts/ &&", + " aws s3 cp ", + { + "Ref": "CloudWatchAgentUrl" + }, + " /etc/cfn/scripts/AmazonCloudWatchAgent.zip", + " --region ", + { + "Ref": "AWS::Region" + }, + " &&", + " chown root:root /etc/cfn/scripts/AmazonCloudWatchAgent.zip &&", + " chmod 700 /etc/cfn/scripts/AmazonCloudWatchAgent.zip" + ] + ] + } + }, + "02-extract-cloudwatch-agent": { + "command": { + "Fn::Join": [ + "", + [ + "yum -y install unzip &&", + "unzip /etc/cfn/scripts/AmazonCloudWatchAgent.zip -d /etc/cfn/scripts/aws-cw-agent" + ] + ] + } + }, + "10-install-cloudwatch-agent": { + "command": { + "Fn::Join": [ + "", + [ + " bash -xe install.sh &&", + " systemctl enable amazon-cloudwatch-agent.service &&", + " systemctl start amazon-cloudwatch-agent.service &&", + " /opt/aws/amazon-cloudwatch-agent/bin/", + "amazon-cloudwatch-agent-ctl", + " -a fetch-config -m ec2 -c", + " file:/opt/aws/amazon-cloudwatch-agent/etc/", + "amazon-cloudwatch-agent.json -s" + ] + ] + }, + "cwd": "/etc/cfn/scripts/aws-cw-agent" + } + }, + "files": { + "/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json": { + "content": { + "Fn::Join": [ + "", + [ + "{", + " \"logs\": {\n", + " \"logs_collected\": {\n", + " \"files\": {\n", + " \"collect_list\": [\n", + " {\n", + " \"file_path\": \"/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log\",\n", + " \"log_group_name\": \"", + { + "Fn::If": [ + "InstallCloudWatchAgent", + { + "Ref": "WatchmakerLaunchConfigLogGroup" + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "\",\n", + " \"log_stream_name\": \"cloudwatch_agent_logs_{instance_id}\",\n", + " \"timestamp_format\": \"%H:%M:%S %y %b %-d\"\n", + " },\n", + " {\n", + " \"file_path\": \"/var/log/cfn-init.log\",\n", + " \"log_group_name\": \"", + { + "Fn::If": [ + "InstallCloudWatchAgent", + { + "Ref": "WatchmakerLaunchConfigLogGroup" + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "\",\n", + " \"log_stream_name\": \"cfn_init_logs_{instance_id}\",\n", + " \"timestamp_format\": \"%H:%M:%S %y %b %-d\"\n", + " },\n", + " {\n", + " \"file_path\": \"/var/log/messages\",\n", + " \"log_group_name\": \"", + { + "Fn::If": [ + "InstallCloudWatchAgent", + { + "Ref": "WatchmakerLaunchConfigLogGroup" + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "\",\n", + " \"log_stream_name\": \"messages_logs_{instance_id}\",\n", + " \"timestamp_format\": \"%H:%M:%S %y %b %-d\"\n", + " },\n", + " {\n", + " \"file_path\": \"/var/log/watchmaker/watchmaker.log\",\n", + " \"log_group_name\": \"", + { + "Fn::If": [ + "InstallCloudWatchAgent", + { + "Ref": "WatchmakerLaunchConfigLogGroup" + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "\",\n", + " \"log_stream_name\": \"watchmaker_logs_{instance_id}\",\n", + " \"timestamp_format\": \"%H:%M:%S %y %b %-d\"\n", + " },\n", + " {\n", + " \"file_path\": \"/var/log/watchmaker/salt_call.debug.log\",\n", + " \"log_group_name\": \"", + { + "Fn::If": [ + "InstallCloudWatchAgent", + { + "Ref": "WatchmakerLaunchConfigLogGroup" + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "\",\n", + " \"log_stream_name\": \"salt_call_debug_logs_{instance_id}\",\n", + " \"timestamp_format\": \"%H:%M:%S %y %b %-d\"\n", + " }\n", + " ]\n", + " }\n", + " },\n", + " \"log_stream_name\": \"default_logs_{instance_id}\"\n", + " }\n", + "}\n" + ] + ] + } + } + } + }, "install-updates": { "commands": { "10-install-updates": { @@ -1470,6 +1665,23 @@ } }, "Type": "AWS::AutoScaling::LaunchConfiguration" + }, + "WatchmakerLaunchConfigLogGroup": { + "Condition": "InstallCloudWatchAgent", + "Properties": { + "LogGroupName": { + "Fn::Join": [ + "", + [ + "/aws/ec2/lx/", + { + "Ref": "AWS::StackName" + } + ] + ] + } + }, + "Type": "AWS::Logs::LogGroup" } } } diff --git a/modules/lx-autoscale/watchmaker-lx-autoscale.params.cfn.json b/modules/lx-autoscale/watchmaker-lx-autoscale.params.cfn.json index 6fcd4392..66e818f2 100644 --- a/modules/lx-autoscale/watchmaker-lx-autoscale.params.cfn.json +++ b/modules/lx-autoscale/watchmaker-lx-autoscale.params.cfn.json @@ -99,6 +99,10 @@ "ParameterKey": "WatchmakerAdminGroups", "ParameterValue": "__WATCHMAKERADMINGROUPS__" }, + { + "ParameterKey": "CloudWatchAgentUrl", + "ParameterValue": "__CWAGENTURL__" + }, { "ParameterKey": "CfnEndpointUrl", "ParameterValue": "__CFNENDPOINTURL__" diff --git a/modules/lx-instance/main.tf b/modules/lx-instance/main.tf index 4f95b64b..50cb9ea5 100644 --- a/modules/lx-instance/main.tf +++ b/modules/lx-instance/main.tf @@ -14,6 +14,7 @@ resource "aws_cloudformation_stack" "watchmaker-lx-instance" { AppVolumeMountPath = "${var.AppVolumeMountPath}" AppVolumeType = "${var.AppVolumeType}" AppVolumeSize = "${var.AppVolumeSize}" + CloudWatchAgentUrl = "${var.CloudWatchAgentUrl}" KeyPairName = "${var.KeyPairName}" InstanceType = "${var.InstanceType}" InstanceRole = "${var.InstanceRole}" diff --git a/modules/lx-instance/variables.tf b/modules/lx-instance/variables.tf index c1e84ff9..cc632f00 100644 --- a/modules/lx-instance/variables.tf +++ b/modules/lx-instance/variables.tf @@ -152,6 +152,12 @@ variable "WatchmakerAdminUsers" { default = "" } +variable "CloudWatchAgentUrl" { + type = "string" + description = "(Optional) S3 URL to CloudWatch Agent installer. Example: s3://amazoncloudwatch-agent/linux/amd64/latest/AmazonCloudWatchAgent.zip" + default = "" +} + variable "CfnEndpointUrl" { type = "string" description = "(Optional) URL to the CloudFormation Endpoint. e.g. https://cloudformation.us-east-1.amazonaws.com" diff --git a/modules/lx-instance/watchmaker-lx-instance.cfn.json b/modules/lx-instance/watchmaker-lx-instance.cfn.json index adcfe4d8..ce1cec55 100644 --- a/modules/lx-instance/watchmaker-lx-instance.cfn.json +++ b/modules/lx-instance/watchmaker-lx-instance.cfn.json @@ -57,6 +57,18 @@ } ] }, + "InstallCloudWatchAgent": { + "Fn::Not": [ + { + "Fn::Equals": [ + { + "Ref": "CloudWatchAgentUrl" + }, + "" + ] + } + ] + }, "InstallUpdates": { "Fn::Not": [ { @@ -306,6 +318,7 @@ "CfnEndpointUrl", "CfnGetPipUrl", "CfnBootstrapUtilsUrl", + "CloudWatchAgentUrl", "ToggleCfnInitUpdate" ] } @@ -323,6 +336,13 @@ "Value": { "Ref": "WatchmakerInstance" } + }, + "WatchmakerInstanceLogGroupName": { + "Condition": "InstallCloudWatchAgent", + "Description": "Log Group Name", + "Value": { + "Ref": "WatchmakerInstanceLogGroup" + } } }, "Parameters": { @@ -413,6 +433,12 @@ "Description": "URL to get-pip.py", "Type": "String" }, + "CloudWatchAgentUrl": { + "AllowedPattern": "^$|^s3://.*$", + "Default": "", + "Description": "(Optional) S3 URL to CloudWatch Agent installer. Example: s3://amazoncloudwatch-agent/linux/amd64/latest/AmazonCloudWatchAgent.zip", + "Type": "String" + }, "InstanceRole": { "Default": "", "Description": "(Optional) IAM instance role to apply to the instance", @@ -549,6 +575,15 @@ "configSets": { "launch": [ "setup", + { + "Fn::If": [ + "InstallCloudWatchAgent", + "install-cloudwatch-agent", + { + "Ref": "AWS::NoValue" + } + ] + }, "watchmaker-install", "watchmaker-launch", { @@ -664,6 +699,173 @@ } } }, + "install-cloudwatch-agent": { + "commands": { + "01-get-cloudwatch-agent": { + "command": { + "Fn::Join": [ + "", + [ + "mkdir -p /etc/cfn/scripts/ &&", + " aws s3 cp ", + { + "Ref": "CloudWatchAgentUrl" + }, + " /etc/cfn/scripts/AmazonCloudWatchAgent.zip", + " --region ", + { + "Ref": "AWS::Region" + }, + " &&", + " chown root:root /etc/cfn/scripts/AmazonCloudWatchAgent.zip &&", + " chmod 700 /etc/cfn/scripts/AmazonCloudWatchAgent.zip" + ] + ] + } + }, + "02-extract-cloudwatch-agent": { + "command": { + "Fn::Join": [ + "", + [ + "yum -y install unzip &&", + "unzip /etc/cfn/scripts/AmazonCloudWatchAgent.zip -d /etc/cfn/scripts/aws-cw-agent" + ] + ] + } + }, + "10-install-cloudwatch-agent": { + "command": { + "Fn::Join": [ + "", + [ + " bash -xe install.sh &&", + " systemctl enable amazon-cloudwatch-agent.service &&", + " systemctl start amazon-cloudwatch-agent.service &&", + " /opt/aws/amazon-cloudwatch-agent/bin/", + "amazon-cloudwatch-agent-ctl", + " -a fetch-config -m ec2 -c", + " file:/opt/aws/amazon-cloudwatch-agent/etc/", + "amazon-cloudwatch-agent.json -s" + ] + ] + }, + "cwd": "/etc/cfn/scripts/aws-cw-agent" + } + }, + "files": { + "/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json": { + "content": { + "Fn::Join": [ + "", + [ + "{", + " \"logs\": {\n", + " \"logs_collected\": {\n", + " \"files\": {\n", + " \"collect_list\": [\n", + " {\n", + " \"file_path\": \"/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log\",\n", + " \"log_group_name\": \"", + { + "Fn::If": [ + "InstallCloudWatchAgent", + { + "Ref": "WatchmakerInstanceLogGroup" + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "\",\n", + " \"log_stream_name\": \"cloudwatch_agent_logs_{instance_id}\",\n", + " \"timestamp_format\": \"%H:%M:%S %y %b %-d\"\n", + " },\n", + " {\n", + " \"file_path\": \"/var/log/cfn-init.log\",\n", + " \"log_group_name\": \"", + { + "Fn::If": [ + "InstallCloudWatchAgent", + { + "Ref": "WatchmakerInstanceLogGroup" + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "\",\n", + " \"log_stream_name\": \"cfn_init_logs_{instance_id}\",\n", + " \"timestamp_format\": \"%H:%M:%S %y %b %-d\"\n", + " },\n", + " {\n", + " \"file_path\": \"/var/log/messages\",\n", + " \"log_group_name\": \"", + { + "Fn::If": [ + "InstallCloudWatchAgent", + { + "Ref": "WatchmakerInstanceLogGroup" + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "\",\n", + " \"log_stream_name\": \"messages_logs_{instance_id}\",\n", + " \"timestamp_format\": \"%H:%M:%S %y %b %-d\"\n", + " },\n", + " {\n", + " \"file_path\": \"/var/log/watchmaker/watchmaker.log\",\n", + " \"log_group_name\": \"", + { + "Fn::If": [ + "InstallCloudWatchAgent", + { + "Ref": "WatchmakerInstanceLogGroup" + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "\",\n", + " \"log_stream_name\": \"watchmaker_logs_{instance_id}\",\n", + " \"timestamp_format\": \"%H:%M:%S %y %b %-d\"\n", + " },\n", + " {\n", + " \"file_path\": \"/var/log/watchmaker/salt_call.debug.log\",\n", + " \"log_group_name\": \"", + { + "Fn::If": [ + "InstallCloudWatchAgent", + { + "Ref": "WatchmakerInstanceLogGroup" + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "\",\n", + " \"log_stream_name\": \"salt_call_debug_logs_{instance_id}\",\n", + " \"timestamp_format\": \"%H:%M:%S %y %b %-d\"\n", + " }\n", + " ]\n", + " }\n", + " },\n", + " \"log_stream_name\": \"default_logs_{instance_id}\"\n", + " }\n", + "}\n" + ] + ] + } + } + } + }, "install-updates": { "commands": { "10-install-updates": { @@ -1495,6 +1697,23 @@ } }, "Type": "AWS::EC2::Instance" + }, + "WatchmakerInstanceLogGroup": { + "Condition": "InstallCloudWatchAgent", + "Properties": { + "LogGroupName": { + "Fn::Join": [ + "", + [ + "/aws/ec2/lx/", + { + "Ref": "AWS::StackName" + } + ] + ] + } + }, + "Type": "AWS::Logs::LogGroup" } } } diff --git a/modules/lx-instance/watchmaker-lx-instance.params.cfn.json b/modules/lx-instance/watchmaker-lx-instance.params.cfn.json index 07ec9282..b3c62a67 100644 --- a/modules/lx-instance/watchmaker-lx-instance.params.cfn.json +++ b/modules/lx-instance/watchmaker-lx-instance.params.cfn.json @@ -99,6 +99,10 @@ "ParameterKey": "WatchmakerOuPath", "ParameterValue": "__WATCHMAKEROUPATH__" }, + { + "ParameterKey": "CloudWatchAgentUrl", + "ParameterValue": "__CWAGENTURL__" + }, { "ParameterKey": "CfnBootstrapUtilsUrl", "ParameterValue": "__CFNBOOTSTRAPUTILSURL__" From 6ea6de4c1fb4144a37733917dba2274d3a49495b Mon Sep 17 00:00:00 2001 From: Long C Lam <31355535+eemperor@users.noreply.github.com> Date: Fri, 23 Mar 2018 11:10:10 -0400 Subject: [PATCH 2/2] Updates command text and adds Outputs section --- .../watchmaker-lx-autoscale.cfn.json | 27 ++++++++++++++++--- .../watchmaker-lx-instance.cfn.json | 6 ++--- .../watchmaker-win-autoscale.cfn.json | 21 +++++++++++++++ 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/modules/lx-autoscale/watchmaker-lx-autoscale.cfn.json b/modules/lx-autoscale/watchmaker-lx-autoscale.cfn.json index c25a718e..b31597cb 100644 --- a/modules/lx-autoscale/watchmaker-lx-autoscale.cfn.json +++ b/modules/lx-autoscale/watchmaker-lx-autoscale.cfn.json @@ -318,6 +318,27 @@ } } }, + "Outputs": { + "WatchmakerAutoScalingGroupId": { + "Description": "Autoscaling Group ID", + "Value": { + "Ref": "WatchmakerAutoScalingGroup" + } + }, + "WatchmakerLaunchConfigId": { + "Description": "Launch Configuration ID", + "Value": { + "Ref": "WatchmakerLaunchConfig" + } + }, + "WatchmakerLaunchConfigLogGroupName": { + "Condition": "InstallCloudWatchAgent", + "Description": "Log Group Name", + "Value": { + "Ref": "WatchmakerLaunchConfigLogGroup" + } + } + }, "Parameters": { "AmiDistro": { "AllowedValues": [ @@ -775,11 +796,9 @@ " bash -xe install.sh &&", " systemctl enable amazon-cloudwatch-agent.service &&", " systemctl start amazon-cloudwatch-agent.service &&", - " /opt/aws/amazon-cloudwatch-agent/bin/", - "amazon-cloudwatch-agent-ctl", + " /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl", " -a fetch-config -m ec2 -c", - " file:/opt/aws/amazon-cloudwatch-agent/etc/", - "amazon-cloudwatch-agent.json -s" + " file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json -s" ] ] }, diff --git a/modules/lx-instance/watchmaker-lx-instance.cfn.json b/modules/lx-instance/watchmaker-lx-instance.cfn.json index ce1cec55..02a6327a 100644 --- a/modules/lx-instance/watchmaker-lx-instance.cfn.json +++ b/modules/lx-instance/watchmaker-lx-instance.cfn.json @@ -742,11 +742,9 @@ " bash -xe install.sh &&", " systemctl enable amazon-cloudwatch-agent.service &&", " systemctl start amazon-cloudwatch-agent.service &&", - " /opt/aws/amazon-cloudwatch-agent/bin/", - "amazon-cloudwatch-agent-ctl", + " /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl", " -a fetch-config -m ec2 -c", - " file:/opt/aws/amazon-cloudwatch-agent/etc/", - "amazon-cloudwatch-agent.json -s" + " file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json -s" ] ] }, diff --git a/modules/win-autoscale/watchmaker-win-autoscale.cfn.json b/modules/win-autoscale/watchmaker-win-autoscale.cfn.json index c128e338..41157f68 100644 --- a/modules/win-autoscale/watchmaker-win-autoscale.cfn.json +++ b/modules/win-autoscale/watchmaker-win-autoscale.cfn.json @@ -237,6 +237,27 @@ } } }, + "Outputs": { + "WatchmakerAutoScalingGroupId": { + "Description": "Autoscaling Group ID", + "Value": { + "Ref": "WatchmakerAutoScalingGroup" + } + }, + "WatchmakerLaunchConfigId": { + "Description": "Launch Configuration ID", + "Value": { + "Ref": "WatchmakerLaunchConfig" + } + }, + "WatchmakerLaunchConfigLogGroupName": { + "Condition": "InstallCloudWatchAgent", + "Description": "Log Group Name", + "Value": { + "Ref": "WatchmakerLaunchConfigLogGroup" + } + } + }, "Parameters": { "AmiId": { "AllowedPattern": "^ami-[0-9a-z]{8}$|^ami-[0-9a-z]{17}$",