Skip to content
This repository was archived by the owner on Oct 28, 2025. It is now read-only.

Commit 410f088

Browse files
committed
Add support for CloudWatch logs (closes #4)
1 parent e6779ac commit 410f088

File tree

4 files changed

+67
-10
lines changed

4 files changed

+67
-10
lines changed

README.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ module "pipeline_rds" {
195195
| Name | Type |
196196
|------|------|
197197
| [aws_autoscaling_group.asg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group) | resource |
198+
| [aws_cloudwatch_log_group.log_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
198199
| [aws_dynamodb_table.kcl](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dynamodb_table) | resource |
199200
| [aws_iam_instance_profile.instance_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource |
200201
| [aws_iam_policy.iam_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
@@ -216,18 +217,26 @@ module "pipeline_rds" {
216217

217218
| Name | Description | Type | Default | Required |
218219
|------|-------------|------|---------|:--------:|
219-
| <a name="input_amazon_linux_2_ami_id"></a> [amazon\_linux\_2\_ami\_id](#input\_amazon\_linux\_2\_ami\_id) | The AMI ID to use which must be based of of Amazon Linux 2; by default the latest community version is used | `string` | `""` | no |
220-
| <a name="input_associate_public_ip_address"></a> [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | Whether to assign a public ip address to this instance | `bool` | `true` | no |
221-
| <a name="input_custom_iglu_resolvers"></a> [custom\_iglu\_resolvers](#input\_custom\_iglu\_resolvers) | The custom Iglu Resolvers that will be used by Enrichment to resolve and validate events | <pre>list(object({<br> name = string<br> priority = number<br> uri = string<br> api_key = string<br> vendor_prefixes = list(string)<br> }))</pre> | `[]` | no |
222220
| <a name="input_db_host"></a> [db\_host](#input\_db\_host) | The hostname of the database to connect to | `string` | n/a | yes |
223221
| <a name="input_db_name"></a> [db\_name](#input\_db\_name) | The name of the database to connect to | `string` | n/a | yes |
224222
| <a name="input_db_password"></a> [db\_password](#input\_db\_password) | The password to use to connect to the database | `string` | n/a | yes |
225223
| <a name="input_db_port"></a> [db\_port](#input\_db\_port) | The port the database is running on | `number` | n/a | yes |
226224
| <a name="input_db_sg_id"></a> [db\_sg\_id](#input\_db\_sg\_id) | The ID of the RDS security group that sits downstream of the webserver | `string` | n/a | yes |
227225
| <a name="input_db_username"></a> [db\_username](#input\_db\_username) | The username to use to connect to the database | `string` | n/a | yes |
226+
| <a name="input_in_stream_name"></a> [in\_stream\_name](#input\_in\_stream\_name) | The name of the input kinesis stream that the Enricher will pull data from | `string` | n/a | yes |
227+
| <a name="input_name"></a> [name](#input\_name) | A name which will be pre-pended to the resources created | `string` | n/a | yes |
228+
| <a name="input_purpose"></a> [purpose](#input\_purpose) | The type of data the loader will be pulling which can be one of ENRICHED\_EVENTS or JSON (Note: JSON can be used for loading bad rows) | `string` | n/a | yes |
229+
| <a name="input_schema_name"></a> [schema\_name](#input\_schema\_name) | The database schema to load data into (e.g atomic \| atomic\_bad) | `string` | n/a | yes |
230+
| <a name="input_ssh_key_name"></a> [ssh\_key\_name](#input\_ssh\_key\_name) | The name of the SSH key-pair to attach to all EC2 nodes deployed | `string` | n/a | yes |
231+
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | The list of subnets to deploy the Postgres Loader across | `list(string)` | n/a | yes |
232+
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | The VPC to deploy the Postgres Loader within | `string` | n/a | yes |
233+
| <a name="input_amazon_linux_2_ami_id"></a> [amazon\_linux\_2\_ami\_id](#input\_amazon\_linux\_2\_ami\_id) | The AMI ID to use which must be based of of Amazon Linux 2; by default the latest community version is used | `string` | `""` | no |
234+
| <a name="input_associate_public_ip_address"></a> [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | Whether to assign a public ip address to this instance | `bool` | `true` | no |
235+
| <a name="input_cloudwatch_logs_enabled"></a> [cloudwatch\_logs\_enabled](#input\_cloudwatch\_logs\_enabled) | Whether application logs should be reported to CloudWatch; by default they are only on the server | `bool` | `false` | no |
236+
| <a name="input_cloudwatch_logs_retention_days"></a> [cloudwatch\_logs\_retention\_days](#input\_cloudwatch\_logs\_retention\_days) | The length of time in days to retain logs for | `number` | `7` | no |
237+
| <a name="input_custom_iglu_resolvers"></a> [custom\_iglu\_resolvers](#input\_custom\_iglu\_resolvers) | The custom Iglu Resolvers that will be used by Enrichment to resolve and validate events | <pre>list(object({<br> name = string<br> priority = number<br> uri = string<br> api_key = string<br> vendor_prefixes = list(string)<br> }))</pre> | `[]` | no |
228238
| <a name="input_default_iglu_resolvers"></a> [default\_iglu\_resolvers](#input\_default\_iglu\_resolvers) | The default Iglu Resolvers that will be used by Enrichment to resolve and validate events | <pre>list(object({<br> name = string<br> priority = number<br> uri = string<br> api_key = string<br> vendor_prefixes = list(string)<br> }))</pre> | <pre>[<br> {<br> "api_key": "",<br> "name": "Iglu Central",<br> "priority": 10,<br> "uri": "http://iglucentral.com",<br> "vendor_prefixes": []<br> },<br> {<br> "api_key": "",<br> "name": "Iglu Central - Mirror 01",<br> "priority": 20,<br> "uri": "http://mirror01.iglucentral.com",<br> "vendor_prefixes": []<br> }<br>]</pre> | no |
229239
| <a name="input_iam_permissions_boundary"></a> [iam\_permissions\_boundary](#input\_iam\_permissions\_boundary) | The permissions boundary ARN to set on IAM roles created | `string` | `""` | no |
230-
| <a name="input_in_stream_name"></a> [in\_stream\_name](#input\_in\_stream\_name) | The name of the input kinesis stream that the Enricher will pull data from | `string` | n/a | yes |
231240
| <a name="input_initial_position"></a> [initial\_position](#input\_initial\_position) | Where to start processing the input Kinesis Stream from (TRIM\_HORIZON or LATEST) | `string` | `"TRIM_HORIZON"` | no |
232241
| <a name="input_instance_type"></a> [instance\_type](#input\_instance\_type) | The instance type to use | `string` | `"t3.micro"` | no |
233242
| <a name="input_kcl_read_max_capacity"></a> [kcl\_read\_max\_capacity](#input\_kcl\_read\_max\_capacity) | The maximum READ capacity for the KCL DynamoDB table | `number` | `10` | no |
@@ -236,16 +245,10 @@ module "pipeline_rds" {
236245
| <a name="input_kcl_write_min_capacity"></a> [kcl\_write\_min\_capacity](#input\_kcl\_write\_min\_capacity) | The minimum WRITE capacity for the KCL DynamoDB table | `number` | `1` | no |
237246
| <a name="input_max_size"></a> [max\_size](#input\_max\_size) | The maximum number of servers in this server-group | `number` | `2` | no |
238247
| <a name="input_min_size"></a> [min\_size](#input\_min\_size) | The minimum number of servers in this server-group | `number` | `1` | no |
239-
| <a name="input_name"></a> [name](#input\_name) | A name which will be pre-pended to the resources created | `string` | n/a | yes |
240-
| <a name="input_purpose"></a> [purpose](#input\_purpose) | The type of data the loader will be pulling which can be one of ENRICHED\_EVENTS or JSON (Note: JSON can be used for loading bad rows) | `string` | n/a | yes |
241-
| <a name="input_schema_name"></a> [schema\_name](#input\_schema\_name) | The database schema to load data into (e.g atomic \| atomic\_bad) | `string` | n/a | yes |
242248
| <a name="input_ssh_ip_allowlist"></a> [ssh\_ip\_allowlist](#input\_ssh\_ip\_allowlist) | The list of CIDR ranges to allow SSH traffic from | `list(any)` | <pre>[<br> "0.0.0.0/0"<br>]</pre> | no |
243-
| <a name="input_ssh_key_name"></a> [ssh\_key\_name](#input\_ssh\_key\_name) | The name of the SSH key-pair to attach to all EC2 nodes deployed | `string` | n/a | yes |
244-
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | The list of subnets to deploy the Postgres Loader across | `list(string)` | n/a | yes |
245249
| <a name="input_tags"></a> [tags](#input\_tags) | The tags to append to this resource | `map(string)` | `{}` | no |
246250
| <a name="input_telemetry_enabled"></a> [telemetry\_enabled](#input\_telemetry\_enabled) | Whether or not to send telemetry information back to Snowplow Analytics Ltd | `bool` | `true` | no |
247251
| <a name="input_user_provided_id"></a> [user\_provided\_id](#input\_user\_provided\_id) | An optional unique identifier to identify the telemetry events emitted by this stack | `string` | `""` | no |
248-
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | The VPC to deploy the Postgres Loader within | `string` | n/a | yes |
249252

250253
## Outputs
251254

main.tf

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ locals {
1717
var.tags,
1818
local.local_tags
1919
)
20+
21+
cloudwatch_log_group_name = "/aws/ec2/${var.name}"
2022
}
2123

2224
data "aws_region" "current" {}
@@ -90,6 +92,17 @@ module "kcl_autoscaling" {
9092
write_max_capacity = var.kcl_write_max_capacity
9193
}
9294

95+
# --- CloudWatch: Logging
96+
97+
resource "aws_cloudwatch_log_group" "log_group" {
98+
count = var.cloudwatch_logs_enabled ? 1 : 0
99+
100+
name = local.cloudwatch_log_group_name
101+
retention_in_days = var.cloudwatch_logs_retention_days
102+
103+
tags = local.tags
104+
}
105+
93106
# --- IAM: Roles & Permissions
94107

95108
resource "aws_iam_role" "iam_role" {
@@ -146,6 +159,17 @@ resource "aws_iam_policy" "iam_policy" {
146159
"Resource": [
147160
"${aws_dynamodb_table.kcl.arn}"
148161
]
162+
},
163+
{
164+
"Effect": "Allow",
165+
"Action": [
166+
"logs:PutLogEvents",
167+
"logs:CreateLogStream",
168+
"logs:DescribeLogStreams"
169+
],
170+
"Resource": [
171+
"arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:${local.cloudwatch_log_group_name}:*"
172+
]
149173
}
150174
]
151175
}
@@ -298,6 +322,9 @@ locals {
298322
schema_name = var.schema_name
299323

300324
telemetry_script = join("", module.telemetry.*.amazon_linux_2_user_data)
325+
326+
cloudwatch_logs_enabled = var.cloudwatch_logs_enabled
327+
cloudwatch_log_group_name = local.cloudwatch_log_group_name
301328
})
302329
}
303330

templates/user-data.sh.tmpl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ function install_docker_ce() {
1515
sudo usermod -a -G docker ec2-user
1616
}
1717

18+
function get_instance_id() {
19+
curl --silent --location "http://169.254.169.254/latest/meta-data/instance-id/"
20+
}
21+
1822
install_docker_ce
1923

2024
sudo mkdir -p $${CONFIG_DIR}
@@ -35,6 +39,11 @@ sudo docker run \
3539
-d \
3640
--name create_schema \
3741
--network host \
42+
%{ if cloudwatch_logs_enabled ~}
43+
--log-driver awslogs \
44+
--log-opt awslogs-group=${cloudwatch_log_group_name} \
45+
--log-opt awslogs-stream=$(get_instance_id) \
46+
%{ endif ~}
3847
-v $${CONFIG_DIR}:/snowplow/config \
3948
-e 'PGUSER=${db_username}' \
4049
-e 'PGPASSWORD=${db_password}' \
@@ -47,8 +56,14 @@ sudo docker run \
4756
--name postgres_loader \
4857
--restart always \
4958
--network host \
59+
%{ if cloudwatch_logs_enabled ~}
60+
--log-driver awslogs \
61+
--log-opt awslogs-group=${cloudwatch_log_group_name} \
62+
--log-opt awslogs-stream=$(get_instance_id) \
63+
%{ else ~}
5064
--log-opt max-size=10m \
5165
--log-opt max-file=5 \
66+
%{ endif ~}
5267
-v $${CONFIG_DIR}:/snowplow/config \
5368
-e 'JAVA_OPTS=-Dorg.slf4j.simpleLogger.defaultLogLevel=info' \
5469
snowplow/snowplow-postgres-loader:${version} \

variables.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@ variable "tags" {
9090
type = map(string)
9191
}
9292

93+
variable "cloudwatch_logs_enabled" {
94+
description = "Whether application logs should be reported to CloudWatch; by default they are only on the server"
95+
default = false
96+
type = bool
97+
}
98+
99+
variable "cloudwatch_logs_retention_days" {
100+
description = "The length of time in days to retain logs for"
101+
default = 7
102+
type = number
103+
}
104+
93105
# --- Configuration options
94106

95107
variable "in_stream_name" {

0 commit comments

Comments
 (0)