Skip to content
This repository has been archived by the owner on Dec 17, 2021. It is now read-only.

Commit

Permalink
Merge pull request #4 from givanovexpe/feature/apiary-replication_enh…
Browse files Browse the repository at this point in the history
…ancements

Feature/apiary replication enhancements
  • Loading branch information
abhimanyugupta07 authored Aug 29, 2019
2 parents 7bf3118 + 868cd67 commit acb100a
Show file tree
Hide file tree
Showing 18 changed files with 532 additions and 231 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [1.2.0] - TBD
### Added
- Support for Docker Auth.
- Ability to store credentials for Docker auth in AWS secrets manager.
- Cloudwatch dashboard.
- Cloudwatch alerts.
- SQS queue permissions.

### Changed
- `selected_tables` variable is now a list.

## [1.1.0] - 2019-02-08
### Added
- New variable for passing Circus Train common configurations to Shunting Yard. eg. Graphite.
Expand Down
46 changes: 23 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

Terraform module for setting up infrastructure for [Shunting Yard](https://github.com/HotelsDotCom/shunting-yard).

For more information please refer to the main [Apiary](https://github.com/ExpediaInc/apiary) project page.
For more information please refer to the main [Apiary](https://github.com/ExpediaGroup/apiary) project page.

## Variables
| Name | Description | Type | Default | Required |
Expand All @@ -14,13 +14,16 @@ For more information please refer to the main [Apiary](https://github.com/Expedi
| ct\_common\_config\_yaml | Common Circus Train configuration to be passed to internal Circus Train instance. It can be used, for example to configure Graphite for Circus Train. Refer to [Circus Train README](https://github.com/HotelsDotCom/circus-train/blob/master/README.md) for an exhaustive list of options supported by Circus Train. | string | n/a | yes |
| docker\_image | Full path of Shunting Yard Docker image. | string | n/a | yes |
| docker\_version | Shunting Yard Docker image version. | string | n/a | yes |
| docker\_registry\_auth\_secret\_name | Docker Registry authentication SecretManager secret name. | string | `` | no |
| instance\_name | Shunting Yard instance name to identify resources in multi-instance deployments. | string | `""` | no |
| memory | The amount of memory (in MiB) allocated to the Shunting Yard container. Valid values: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html | string | `"4096"` | no |
| metastore\_events\_sns\_topic | SNS Topic for Hive Metastore events. | string | n/a | yes |
| selected\_tables | Tables selected for Shunting Yard Replication. Supported Format: `database_1.table_1, database_2.table_2` | string | n/a | yes |
| shuntingyard\_sqs\_queue\_wait\_timeout | Shunting Yard SQS queue wait timeout (in seconds) | string | 15 | no |
| shuntingyard\_sqs\_queue\_stale\_messages\_timeout | Shunting Yard SQS queue stale messages alert timeout (in seconds) | string | 300 | no |
| selected\_tables | Tables selected for Shunting Yard Replication. Supported Format: `[ "database_1.table_1", "database_2.table_2" ]` | list | [] | no |
| source\_metastore\_uri | Source Metastore URI for Shunting Yard. | string | n/a | yes |
| subnets | ECS container subnets. | list | n/a | yes |
| tags | A map of tags to apply to resources. | map | `<map>` | no |
| shuntingyard\_tags | A map of tags to apply to resources. | map | `<map>` | no |
| target\_metastore\_uri | Target Metastore URI for Shunting Yard. | string | n/a | yes |
| vpc\_id | VPC ID. | string | n/a | yes |

Expand All @@ -29,26 +32,23 @@ For more information please refer to the main [Apiary](https://github.com/Expedi
Example module invocation:
```
module "apiary-shuntingyard" {
source = "git::https://github.com/ExpediaInc/apiary-replication.git?ref=master"
instance_name = "shuntingyard-test"
aws_region = "us-west-2"
vpc_id = "vpc-1"
subnets = ["subnet-1", "subnet-2"]
allowed_s3_buckets = ["bucket-1", "bucket-2"]
tags = {
Name = "Apiary-Shuntingyard"
Team = "Operations"
}
source_metastore_uri = "thrift://ip-address:9083"
target_metastore_uri = "thrift://ip-address:9083"
metastore_events_sns_topic = "arn:aws:sns:us-west-2:1234567:metastore-events-sns-topic"
selected_tables = "database_1.table_1, database_2.table_2"
ct_common_config_yaml = "${data.template_file.ct_common_config_yaml.rendered}"
docker_image = "your.docker.repo/apiary-shuntingyard"
docker_version = "latest"
source = "git::https://github.com/ExpediaGroup/apiary-replication.git"
aws_region = "us-west-2"
vpc_id = "vpc-1"
subnets = ["subnet-1", "subnet-2"]
instance_name = "shuntingyard-test"
docker_image = "your.docker.repo/apiary-shuntingyard"
docker_version = "latest"
ct_common_config_yaml = "${data.template_file.ct_common_config_yaml.rendered}"
source_metastore_uri = "thrift://ip-address:9083"
target_metastore_uri = "thrift://ip-address:9083"
metastore_events_sns_topic = "arn:aws:sns:us-west-2:1234567:metastore-events-sns-topic"
selected_tables = [ "database_1.table_1", "database_2.table_2" ]
allowed_s3_buckets = [ "bucket-1", "bucket-2" ]
shuntingyard_tags = {
Name = "Apiary Replication"
Team = "Operations"
}
}
```

Expand Down
169 changes: 169 additions & 0 deletions cloudwatch.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/**
* Copyright (C) 2019 Expedia, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
*/

data "template_file" "ecs_widgets" {
template = <<EOF
{
"type":"metric",
"width":12,
"height":6,
"properties":{
"metrics":[
[ "AWS/ECS", "CPUUtilization", "ServiceName", "${local.instance_alias}-service", "ClusterName", "${local.instance_alias}" ]
],
"period":300,
"stat":"Average",
"region":"${var.aws_region}",
"title":"Shunting Yard ECS CPU Utilization"
}
},
{
"type":"metric",
"width":12,
"height":6,
"properties":{
"metrics":[
[ "AWS/ECS", "MemoryUtilization", "ServiceName", "${local.instance_alias}-service", "ClusterName", "${local.instance_alias}" ]
],
"period":300,
"stat":"Average",
"region":"${var.aws_region}",
"title":"Shunting Yard ECS Memory Utilization"
}
},
EOF
}

data "template_file" "sqs_widgets" {
template = <<EOF
{
"type":"metric",
"width":12,
"height":6,
"properties":{
"metrics": [
[ "AWS/SQS", "NumberOfMessagesSent", "QueueName", "${local.instance_alias}-sqs-queue" ],
[ "AWS/SQS", "NumberOfMessagesReceived", "QueueName", "${local.instance_alias}-sqs-queue" ]
],
"period":300,
"stat":"Average",
"region": "${var.aws_region}",
"title": "Shunting Yard SQS Sent & Received Messages"
}
},
{
"type":"metric",
"width":12,
"height":6,
"properties":{
"metrics": [
[ "AWS/SQS", "ApproximateNumberOfMessagesVisible", "QueueName", "${local.instance_alias}-sqs-queue" ],
[ "AWS/SQS", "ApproximateNumberOfMessagesDelayed", "QueueName", "${local.instance_alias}-sqs-queue" ],
[ "AWS/SQS", "ApproximateNumberOfMessagesNotVisible", "QueueName", "${local.instance_alias}-sqs-queue" ]
],
"period":300,
"stat":"Average",
"region": "${var.aws_region}",
"title": "Shunting Yard SQS Queue Size Metrics"
}
},
{
"type":"metric",
"width":12,
"height":6,
"properties":{
"metrics": [
[ "AWS/SQS", "NumberOfMessagesDeleted", "QueueName", "${local.instance_alias}-sqs-queue" ]
],
"period":300,
"stat":"Average",
"region": "${var.aws_region}",
"title": "Shunting Yard SQS Deleted Messages"
}
},
{
"type":"metric",
"width":12,
"height":6,
"properties":{
"metrics": [
[ "AWS/SQS", "ApproximateAgeOfOldestMessage", "QueueName", "${local.instance_alias}-sqs-queue" ]
],
"period":300,
"stat":"Average",
"view": "singleValue",
"region": "${var.aws_region}",
"title": "Shunting Yard SQS Age of Oldest Message (s)"
}
}
EOF
}

resource "aws_cloudwatch_dashboard" "shuntingyard" {
dashboard_name = "${local.instance_alias}-${var.aws_region}"

dashboard_body = <<EOF
{
"widgets": [
${join("", data.template_file.ecs_widgets.*.rendered)}
${join("", data.template_file.sqs_widgets.*.rendered)}
]
}
EOF
}

locals {
alerts = [
{
alarm_name = "${local.instance_alias}-cpu"
namespace = "AWS/ECS"
metric_name = "CPUUtilization"
threshold = "90"
},
{
alarm_name = "${local.instance_alias}-memory"
namespace = "AWS/ECS"
metric_name = "MemoryUtilization"
threshold = "80"
},
{
alarm_name = "${local.instance_alias}-stale-messages"
namespace = "AWS/SQS"
metric_name = "ApproximateAgeOfOldestMessage"
threshold = "${var.shuntingyard_sqs_queue_stale_messages_timeout}"
},
]

dimensions = [
{
ClusterName = "${local.instance_alias}"
ServiceName = "${local.instance_alias}-service"
},
{
ClusterName = "${local.instance_alias}"
ServiceName = "${local.instance_alias}-service"
},
{
QueueName = "${local.instance_alias}-sqs-queue"
},
]
}

resource "aws_cloudwatch_metric_alarm" "shuntingyard_alert" {
count = "${length(local.alerts)}"
alarm_name = "${lookup(local.alerts[count.index], "alarm_name")}"
comparison_operator = "${lookup(local.alerts[count.index], "comparison_operator", "GreaterThanOrEqualToThreshold")}"
metric_name = "${lookup(local.alerts[count.index], "metric_name")}"
namespace = "${lookup(local.alerts[count.index], "namespace")}"
period = "${lookup(local.alerts[count.index], "period", "120")}"
evaluation_periods = "${lookup(local.alerts[count.index], "evaluation_periods", "2")}"
statistic = "Average"
threshold = "${lookup(local.alerts[count.index], "threshold")}"

insufficient_data_actions = []
dimensions = "${local.dimensions[count.index]}"
alarm_actions = ["${aws_sns_topic.shuntingyard_ops_sns.arn}"]
}
7 changes: 6 additions & 1 deletion common.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (C) 2019 Expedia Inc.
* Copyright (C) 2019 Expedia, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
Expand All @@ -11,3 +11,8 @@ locals {
data "aws_vpc" "shuntingyard_vpc" {
id = "${var.vpc_id}"
}

data "aws_secretsmanager_secret" "docker_registry" {
count = "${var.docker_registry_auth_secret_name == "" ? 0 : 1}"
name = "${var.docker_registry_auth_secret_name}"
}
40 changes: 40 additions & 0 deletions ecs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright (C) 2019 Expedia, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
*/

resource "aws_ecs_cluster" "shuntingyard" {
name = "${local.instance_alias}"
tags = "${var.shuntingyard_tags}"
}

resource "aws_cloudwatch_log_group" "shuntingyard_ecs" {
name = "${local.instance_alias}"
tags = "${var.shuntingyard_tags}"
}

resource "aws_ecs_task_definition" "shuntingyard" {
family = "${local.instance_alias}"
task_role_arn = "${aws_iam_role.shuntingyard_task.arn}"
execution_role_arn = "${aws_iam_role.shuntingyard_task_exec.arn}"
network_mode = "awsvpc"
memory = "${var.memory}"
cpu = "${var.cpu}"
requires_compatibilities = ["EC2", "FARGATE"]
container_definitions = "${data.template_file.shuntingyard.rendered}"
tags = "${var.shuntingyard_tags}"
}

resource "aws_ecs_service" "shuntingyard_service" {
name = "${local.instance_alias}-service"
launch_type = "FARGATE"
cluster = "${aws_ecs_cluster.shuntingyard.id}"
task_definition = "${aws_ecs_task_definition.shuntingyard.arn}"
desired_count = "1"

network_configuration {
security_groups = ["${aws_security_group.shuntingyard_sg.id}"]
subnets = ["${var.subnets}"]
}
}
39 changes: 39 additions & 0 deletions iam-policy-s3-buckets.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright (C) 2019 Expedia, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
*/

resource "aws_iam_role_policy" "s3_for_shuntingyard" {
name = "s3"
role = "${aws_iam_role.shuntingyard_task.id}"

policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:Get*",
"s3:List*",
"s3:PutBucketLogging",
"s3:PutBucketNotification",
"s3:PutBucketVersioning",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectTagging",
"s3:PutObjectVersionAcl",
"s3:PutObjectVersionTagging"
],
"Resource": [
"${join("\",\"", formatlist("arn:aws:s3:::%s",var.allowed_s3_buckets))}",
"${join("\",\"", formatlist("arn:aws:s3:::%s/*",var.allowed_s3_buckets))}"
]
}
]
}
EOF
}
22 changes: 22 additions & 0 deletions iam-policy-secretsmanager.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Copyright (C) 2019 Expedia, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
*/

resource "aws_iam_role_policy" "secretsmanager_for_ecs_task_exec" {
count = "${var.docker_registry_auth_secret_name != "" ? 1 : 0}"
name = "secretsmanager-exec"
role = "${aws_iam_role.shuntingyard_task_exec.id}"

policy = <<EOF
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": [ "${join("\",\"", concat(data.aws_secretsmanager_secret.docker_registry.*.arn))}" ]
}
}
EOF
}
Loading

0 comments on commit acb100a

Please sign in to comment.