Skip to content

Commit f727a31

Browse files
npalmgertjanmaas
andauthored
Feature/log to cloudwatch (#375)
* feat: stream logging to cloudwatch of the agent, user_data en system messages * Refactor and make cloudwatch agent optional * Apply suggestions from code review Co-authored-by: Gertjan Maas <[email protected]> * Update docs Co-authored-by: Gertjan Maas <[email protected]>
1 parent d590514 commit f727a31

File tree

9 files changed

+168
-49
lines changed

9 files changed

+168
-49
lines changed

README.md

Lines changed: 52 additions & 47 deletions
Large diffs are not rendered by default.

main.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ module "runners" {
9292
lambda_timeout_scale_up = var.runners_scale_up_lambda_timeout
9393
lambda_timeout_scale_down = var.runners_scale_down_lambda_timeout
9494
logging_retention_in_days = var.logging_retention_in_days
95+
enable_cloudwatch_agent = var.enable_cloudwatch_agent
96+
cloudwatch_config = var.cloudwatch_config
97+
runner_log_files = var.runner_log_files
9598

9699
instance_profile_path = var.instance_profile_path
97100
role_path = var.role_path

modules/runners/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ No requirements.
6666
| ami\_owners | The list of owners used to select the AMI of action runner instances. | `list(string)` | <pre>[<br> "amazon"<br>]</pre> | no |
6767
| aws\_region | AWS region. | `string` | n/a | yes |
6868
| block\_device\_mappings | The EC2 instance block device configuration. Takes the following keys: `device_name`, `delete_on_termination`, `volume_type`, `volume_size`, `encrypted`, `iops` | `map(string)` | `{}` | no |
69+
| cloudwatch\_config | (optional) Replaces the module default cloudwatch log config. See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html for details. | `string` | `null` | no |
6970
| create\_service\_linked\_role\_spot | (optional) create the serviced linked role for spot instances that is required by the scale-up lambda. | `bool` | `false` | no |
71+
| enable\_cloudwatch\_agent | Enabling the cloudwatch agent on the ec2 runner instances, the runner contains default config. Configuration can be overridden via `cloudwatch_config`. | `bool` | `true` | no |
7072
| enable\_organization\_runners | n/a | `bool` | n/a | yes |
7173
| enable\_ssm\_on\_runners | Enable to allow access the runner instances for debugging purposes via SSM. Note that this adds additional permissions to the runner instances. | `bool` | n/a | yes |
7274
| encryption | KMS key to encrypted lambda environment secrets. Either provide a key and `encrypt` set to `true`. Or set the key to `null` and encrypt to `false`. | <pre>object({<br> kms_key_id = string<br> encrypt = bool<br> })</pre> | n/a | yes |
@@ -88,6 +90,8 @@ No requirements.
8890
| runner\_architecture | The platform architecture of the runner instance\_type. | `string` | `"x64"` | no |
8991
| runner\_as\_root | Run the action runner under the root user. | `bool` | `false` | no |
9092
| runner\_extra\_labels | Extra labels for the runners (GitHub). Separate each label by a comma | `string` | `""` | no |
93+
| runner\_iam\_role\_managed\_policy\_arns | Attach AWS or customer-managed IAM policies (by ARN) to the runner IAM role | `list(string)` | `[]` | no |
94+
| runner\_log\_files | (optional) List of logfiles to send to cloudwatch. | <pre>list(object({<br> file_path = string<br> log_stream_name = string<br> }))</pre> | <pre>[<br> {<br> "file_path": "/var/log/messages",<br> "log_stream_name": "{instance_id}/messages"<br> },<br> {<br> "file_path": "/var/log/user-data.log",<br> "log_stream_name": "{instance_id}/user_data"<br> },<br> {<br> "file_path": "/home/ec2-user/actions-runner/_diag/Runner_**.log",<br> "log_stream_name": "{instance_id}/runner"<br> }<br>]</pre> | no |
9195
| runners\_lambda\_s3\_key | S3 key for runners lambda function. Required if using S3 bucket to specify lambdas. | `any` | `null` | no |
9296
| runners\_lambda\_s3\_object\_version | S3 object version for runners lambda function. Useful if S3 versioning is enabled on source bucket. | `any` | `null` | no |
9397
| runners\_maximum\_count | The maximum number of runners that will be created. | `number` | `3` | no |

modules/runners/logging.tf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
locals {
2+
logfiles = var.enable_cloudwatch_agent ? [for l in var.runner_log_files : merge(l, { "log_group_name" : aws_cloudwatch_log_group.runners[0].name })] : []
3+
}
4+
5+
resource "aws_ssm_parameter" "cloudwatch_agent_config_runner" {
6+
count = var.enable_cloudwatch_agent ? 1 : 0
7+
name = "${var.environment}-cloudwatch_agent_config_runner"
8+
type = "String"
9+
value = var.cloudwatch_config != null ? var.cloudwatch_config : templatefile("${path.module}/templates/cloudwatch_config.json", {
10+
logfiles = jsonencode(local.logfiles)
11+
})
12+
tags = local.tags
13+
}
14+
15+
resource "aws_cloudwatch_log_group" "runners" {
16+
count = var.enable_cloudwatch_agent ? 1 : 0
17+
name = "${var.environment}/runners"
18+
retention_in_days = var.logging_retention_in_days
19+
tags = local.tags
20+
}

modules/runners/main.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ resource "aws_launch_template" "runner" {
8181
s3_location_runner_distribution = var.s3_location_runner_binaries
8282
service_user = var.runner_as_root ? "root" : "ec2-user"
8383
runner_architecture = var.runner_architecture
84+
enable_cloudwatch_agent = var.enable_cloudwatch_agent
85+
ssm_key_cloudwatch_agent_config = var.enable_cloudwatch_agent ? aws_ssm_parameter.cloudwatch_agent_config_runner[0].name : ""
8486
}))
8587

8688
tags = local.tags
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"agent": {
3+
"metrics_collection_interval": 5
4+
},
5+
"logs": {
6+
"logs_collected": {
7+
"files": {
8+
"collect_list": ${logfiles}
9+
}
10+
}
11+
}
12+
}

modules/runners/templates/user-data.sh

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ ${pre_install}
55

66
yum update -y
77

8+
%{ if enable_cloudwatch_agent ~}
9+
yum install amazon-cloudwatch-agent -y
10+
amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c ssm:${ssm_key_cloudwatch_agent_config}
11+
%{ endif ~}
12+
813
# Install docker
914
amazon-linux-extras install docker
1015
service docker start
@@ -77,8 +82,8 @@ REGION=$(curl -s 169.254.169.254/latest/dynamic/instance-identity/document | jq
7782

7883
echo wait for configuration
7984
while [[ $(aws ssm get-parameters --names ${environment}-$INSTANCE_ID --with-decryption --region $REGION | jq -r ".Parameters | .[0] | .Value") == null ]]; do
80-
echo Waiting for configuration ...
81-
sleep 1
85+
echo Waiting for configuration ...
86+
sleep 1
8287
done
8388
CONFIG=$(aws ssm get-parameters --names ${environment}-$INSTANCE_ID --with-decryption --region $REGION | jq -r ".Parameters | .[0] | .Value")
8489
aws ssm delete-parameter --name ${environment}-$INSTANCE_ID --region $REGION

modules/runners/variables.tf

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,37 @@ variable "runner_iam_role_managed_policy_arns" {
244244
type = list(string)
245245
default = []
246246
}
247+
248+
variable "enable_cloudwatch_agent" {
249+
description = "Enabling the cloudwatch agent on the ec2 runner instances, the runner contains default config. Configuration can be overridden via `cloudwatch_config`."
250+
type = bool
251+
default = true
252+
}
253+
254+
variable "cloudwatch_config" {
255+
description = "(optional) Replaces the module default cloudwatch log config. See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html for details."
256+
type = string
257+
default = null
258+
}
259+
260+
variable "runner_log_files" {
261+
description = "(optional) List of logfiles to send to cloudwatch."
262+
type = list(object({
263+
file_path = string
264+
log_stream_name = string
265+
}))
266+
default = [
267+
{
268+
"file_path" : "/var/log/messages",
269+
"log_stream_name" : "{instance_id}/messages"
270+
},
271+
{
272+
"file_path" : "/var/log/user-data.log",
273+
"log_stream_name" : "{instance_id}/user_data"
274+
},
275+
{
276+
"file_path" : "/home/ec2-user/actions-runner/_diag/Runner_**.log",
277+
"log_stream_name" : "{instance_id}/runner"
278+
}
279+
]
280+
}

variables.tf

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,37 @@ variable "runner_iam_role_managed_policy_arns" {
262262
type = list(string)
263263
default = []
264264
}
265+
266+
variable "enable_cloudwatch_agent" {
267+
description = "Enabling the cloudwatch agent on the ec2 runner instances, the runner contains default config. Configuration can be overridden via `cloudwatch_config`."
268+
type = bool
269+
default = true
270+
}
271+
272+
variable "cloudwatch_config" {
273+
description = "(optional) Replaces the module default cloudwatch log config. See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html for details."
274+
type = string
275+
default = null
276+
}
277+
278+
variable "runner_log_files" {
279+
description = "(optional) List of logfiles to send to cloudwatch."
280+
type = list(object({
281+
file_path = string
282+
log_stream_name = string
283+
}))
284+
default = [
285+
{
286+
"file_path" : "/var/log/messages",
287+
"log_stream_name" : "{instance_id}/messages"
288+
},
289+
{
290+
"file_path" : "/var/log/user-data.log",
291+
"log_stream_name" : "{instance_id}/user_data"
292+
},
293+
{
294+
"file_path" : "/home/ec2-user/actions-runner/_diag/Runner_**.log",
295+
"log_stream_name" : "{instance_id}/runner"
296+
}
297+
]
298+
}

0 commit comments

Comments
 (0)