Skip to content

Commit

Permalink
Merge pull request #10 from turnerlabs/updates-10-3-19
Browse files Browse the repository at this point in the history
  • Loading branch information
jritsema authored Oct 4, 2019
2 parents 73219be + 69c0365 commit 941cc4e
Show file tree
Hide file tree
Showing 8 changed files with 659 additions and 36 deletions.
4 changes: 4 additions & 0 deletions env/dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ The optional components can be removed by simply deleting the `.tf` file.
| [autoscale-perf.tf][edap] | Performance-based auto scaling | Yes |
| [autoscale-time.tf][edat] | Time-based auto scaling | Yes |
| [logs-logzio.tf][edll] | Ship container logs to logz.io | Yes |
| [secretsmanager.tf][edsm] | Add a Secrets Manager secret with a CMK KMS key. Also gives app role and ECS task definition role access to read secrets from Secrets Manager | Yes |
| [ssm-parameters.tf][ssm] | Add a CMK KMS key for use with SSM Parameter Store. Also gives ECS task definition role access to read secrets from parameter store. | Yes |


## Usage
Expand Down Expand Up @@ -92,3 +94,5 @@ $ terraform apply
[edll]: logs-logzio.tf
[alb-docs]: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html
[up]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html
[edsm]: secretsmanager.tf
[ssm]: ssm-parameters.tf
120 changes: 120 additions & 0 deletions env/dev/ecs-event-stream.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**
* ECS Event Stream
* This component gives you full access to the ECS event logs
* for your cluster by creating a cloudwatch event rule that listens for
* events for this cluster and calls a lambda that writes them to cloudwatch logs.
* It then adds a cloudwatch dashboard the displays the results of a
* logs insights query against the lambda logs
*/

# cw event rule
resource "aws_cloudwatch_event_rule" "ecs_event_stream" {
name = "${var.app}-${var.environment}-ecs-event-stream"
description = "Passes ecs event logs for ${var.app}-${var.environment} to a lambda that writes them to cw logs"

event_pattern = <<PATTERN
{
"detail": {
"clusterArn": ["${aws_ecs_cluster.app.arn}"]
}
}
PATTERN

}

resource "aws_cloudwatch_event_target" "ecs_event_stream" {
rule = aws_cloudwatch_event_rule.ecs_event_stream.name
arn = aws_lambda_function.ecs_event_stream.arn
}

data "template_file" "lambda_source" {
template = <<EOF
exports.handler = (event, context, callback) => {
console.log(JSON.stringify(event));
}
EOF

}

data "archive_file" "lambda_zip" {
type = "zip"
source_content = data.template_file.lambda_source.rendered
source_content_filename = "index.js"
output_path = "lambda-${var.app}.zip"
}

resource "aws_lambda_permission" "ecs_event_stream" {
statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.ecs_event_stream.arn
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.ecs_event_stream.arn
}

resource "aws_lambda_function" "ecs_event_stream" {
function_name = "${var.app}-${var.environment}-ecs-event-stream"
role = aws_iam_role.ecs_event_stream.arn
filename = data.archive_file.lambda_zip.output_path
source_code_hash = data.archive_file.lambda_zip.output_base64sha256
handler = "index.handler"
runtime = "nodejs8.10"
tags = var.tags
}

resource "aws_lambda_alias" "ecs_event_stream" {
name = aws_lambda_function.ecs_event_stream.function_name
description = "latest"
function_name = aws_lambda_function.ecs_event_stream.function_name
function_version = "$LATEST"
}

resource "aws_iam_role" "ecs_event_stream" {
name = aws_cloudwatch_event_rule.ecs_event_stream.name

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF

}

resource "aws_iam_role_policy_attachment" "ecs_event_stream" {
role = aws_iam_role.ecs_event_stream.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

# cloudwatch dashboard with logs insights query
resource "aws_cloudwatch_dashboard" "ecs-event-stream" {
dashboard_name = "${var.app}-${var.environment}-ecs-event-stream"

dashboard_body = <<EOF
{
"widgets": [
{
"type": "log",
"x": 0,
"y": 0,
"width": 24,
"height": 18,
"properties": {
"query": "SOURCE '/aws/lambda/${var.app}-${var.environment}-ecs-event-stream' | fields @timestamp as time, detail.desiredStatus as desired, detail.lastStatus as latest, detail.stoppedReason as reason, detail.containers.0.reason as container_reason, detail.taskDefinitionArn as task_definition\n| filter @type != \"START\" and @type != \"END\" and @type != \"REPORT\"\n| sort detail.updatedAt desc, detail.version desc\n| limit 100",
"region": "us-east-1",
"title": "ECS Event Log"
}
}
]
}
EOF
}
13 changes: 9 additions & 4 deletions env/dev/ecs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,14 @@ resource "aws_iam_role_policy_attachment" "ecsTaskExecutionRole_policy" {
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}

resource "aws_cloudwatch_log_group" "logs" {
name = "/fargate/service/${var.app}-${var.environment}"
retention_in_days = "14"
tags = var.tags
variable "logs_retention_in_days" {
type = number
default = 90
description = "Specifies the number of days you want to retain log events"
}

resource "aws_cloudwatch_log_group" "logs" {
name = "/fargate/service/${var.app}-${var.environment}"
retention_in_days = var.logs_retention_in_days
tags = var.tags
}
17 changes: 16 additions & 1 deletion env/dev/fargate-create.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,19 @@ prompts:
default: "no"
filesToDeleteIfNo:
- "logs-logzio.tf"
- "logs-logzio.zip"
- "logs-logzio.zip"

- question: "Would you like to use Secrets Manager for secrets?"
default: "no"
filesToDeleteIfNo:
- "secretsmanager.tf"

- question: "Would you like to use SSM Parameter Store for secrets?"
default: "no"
filesToDeleteIfNo:
- "ssm-parameters.tf"

- question: "Would you like an ECS event log dashboard?"
default: "yes"
filesToDeleteIfNo:
- "ecs-event-stream.tf"
56 changes: 27 additions & 29 deletions env/dev/logs-logzio.tf
Original file line number Diff line number Diff line change
Expand Up @@ -55,41 +55,39 @@ EOF

#function code from logzio: https://github.com/logzio/cloudwatch-logs-shipper-lambda
resource "aws_lambda_function" "lambda_logz" {
function_name = "${var.app}-${var.environment}-logz"
description = "Sends Cloudwatch logs to logz."
runtime = "python2.7"
timeout = 60
memory_size = 512
role = aws_iam_role.iam_for_lambda_logz.arn
handler = "lambda_function.lambda_handler"
filename = "logs-logzio.zip"
source_code_hash = filebase64sha256("logs-logzio.zip")
function_name = "${var.app}-${var.environment}-logz"
description = "Sends Cloudwatch logs to logz."
runtime = "python2.7"
timeout = 60
memory_size = 512
role = aws_iam_role.iam_for_lambda_logz.arn
handler = "lambda_function.lambda_handler"
filename = "logs-logzio.zip"
source_code_hash = filebase64sha256("logs-logzio.zip")

tags = var.tags
tags = var.tags

environment {
variables = {
TOKEN = var.logz_token
URL = var.logz_url
TYPE = "elb"
}
}
environment {
variables = {
TOKEN = var.logz_token
URL = var.logz_url
TYPE = "elb"
}
}
}

resource "aws_lambda_permission" "allow_cloudwatch" {
statement_id = "${var.app}-${var.environment}-logz"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.lambda_logz.arn
principal = "logs.${var.region}.amazonaws.com"
source_arn = aws_cloudwatch_log_group.logs.arn
statement_id = "${var.app}-${var.environment}-logz"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.lambda_logz.arn
principal = "logs.${var.region}.amazonaws.com"
source_arn = aws_cloudwatch_log_group.logs.arn
}

resource "aws_cloudwatch_log_subscription_filter" "cloudwatch_lambda_subscription" {
depends_on = [aws_lambda_permission.allow_cloudwatch]
name = "${var.app}-${var.environment}-logz"
log_group_name = aws_cloudwatch_log_group.logs.name
filter_pattern = ""
destination_arn = aws_lambda_function.lambda_logz.arn
distribution = "ByLogStream"
depends_on = [aws_lambda_permission.allow_cloudwatch]
name = "${var.app}-${var.environment}-logz"
log_group_name = aws_cloudwatch_log_group.logs.name
filter_pattern = ""
destination_arn = aws_lambda_function.lambda_logz.arn
}

3 changes: 1 addition & 2 deletions env/dev/main.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
terraform {
required_version = ">= 0.12.0"
required_version = ">= 0.12"

backend "s3" {
region = "us-east-1"
Expand Down Expand Up @@ -45,4 +45,3 @@ output "scale_out" {
output "aws_profile" {
value = var.aws_profile
}

Loading

0 comments on commit 941cc4e

Please sign in to comment.