Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

10-3-19 updates #10

Merged
merged 3 commits into from
Oct 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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