Skip to content

Instantly share code, notes, and snippets.

@aaronrea
Created July 28, 2020 20:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aaronrea/9c97a80553bf8a4e6e42e32f662dc064 to your computer and use it in GitHub Desktop.
Save aaronrea/9c97a80553bf8a4e6e42e32f662dc064 to your computer and use it in GitHub Desktop.
Cloudknocking Terraform PoC
#########################
##
## variables
##
#########################
variable zone_id {}
variable region {
default = "us-east-1"
}
# Use SMS for quick'n'dirty notification testing
variable notification_target {}
#########################
##
## terraform setup
##
#########################
terraform {
required_version = ">= 0.12"
backend "local" {}
}
provider "aws" {
alias = "us-east-1"
region = var.region
}
data "aws_caller_identity" "current" {}
#########################
##
## log groups, query, requisite policy
##
#########################
resource "aws_cloudwatch_log_group" "aws_route53_logrp" {
name = "/aws/route53/${var.zone_id}"
retention_in_days = 1
}
# Example CloudWatch log resource policy to allow Route53 to write logs
# to any log group under /aws/route53/*
data "aws_iam_policy_document" "route53-query-logging-policy" {
statement {
actions = [
"logs:CreateLogStream",
"logs:PutLogEvents",
]
resources = ["arn:aws:logs:${var.region}:${data.aws_caller_identity.current.account_id}:log-group:/aws/route53/*"]
principals {
identifiers = ["route53.amazonaws.com"]
type = "Service"
}
}
}
resource "aws_cloudwatch_log_resource_policy" "route53-query-logging-policy" {
provider = aws.us-east-1
policy_document = data.aws_iam_policy_document.route53-query-logging-policy.json
policy_name = "route53-query-logging-policy-${var.zone_id}"
}
resource "aws_route53_query_log" "query_log" {
depends_on = [aws_cloudwatch_log_resource_policy.route53-query-logging-policy]
cloudwatch_log_group_arn = aws_cloudwatch_log_group.aws_route53_logrp.arn
zone_id = var.zone_id
}
#########################
##
## metric filter and alarm
##
#########################
resource "aws_cloudwatch_log_metric_filter" "cloudknocking-metric-filter" {
name = "cloudknocking-metric-filter"
pattern = "cloudknocking"
log_group_name = aws_cloudwatch_log_group.aws_route53_logrp.name
metric_transformation {
name = "KnockCount"
namespace = "CloudKnockingNamespace"
value = "1"
default_value = "0"
}
}
resource "aws_cloudwatch_metric_alarm" "cloudkncocking-alarm" {
alarm_name = "cloudknocking-alarm"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "1"
metric_name = "KnockCount"
namespace = "CloudKnockingNamespace"
period = "10"
statistic = "Sum"
threshold = "0"
alarm_description = "r53 query trip alarm"
## nonBreaching means green on the dashboard.
treat_missing_data = "notBreaching"
}
#########################
##
## event rule and target spec
##
#########################
resource "aws_cloudwatch_event_rule" "cloudknocking-rule" {
name = "CloudKnockingNamespace"
## not many detailed examples of event patterns out in the wild.
## for complex situations, refer to the Cloudwatch Event spec for a service
event_pattern = <<PATTERN
{
"source": [
"aws.cloudwatch"
],
"detail-type": [
"CloudWatch Alarm State Change"
],
"resources": ["arn:aws:cloudwatch:${var.region}:${data.aws_caller_identity.current.account_id}:alarm:${aws_cloudwatch_metric_alarm.cloudkncocking-alarm.alarm_name}"],
"detail": {
"state": {
"value": ["ALARM"]
}
}
}
PATTERN
}
resource "aws_cloudwatch_event_target" "event_target" {
rule = aws_cloudwatch_event_rule.cloudknocking-rule.name
target_id = "SendToSNS"
arn = aws_sns_topic.notification_topic.arn
}
resource "aws_sns_topic" "notification_topic" {
name = "ck_topic"
}
resource "aws_sns_topic_policy" "default" {
arn = aws_sns_topic.notification_topic.arn
policy = data.aws_iam_policy_document.sns_topic_policy.json
}
data "aws_iam_policy_document" "sns_topic_policy" {
statement {
effect = "Allow"
actions = ["SNS:Publish"]
principals {
type = "Service"
identifiers = ["events.amazonaws.com"]
}
resources = [aws_sns_topic.notification_topic.arn]
}
}
resource "aws_sns_topic_subscription" "sms_subscription" {
topic_arn = aws_sns_topic.notification_topic.arn
protocol = "sms"
endpoint = var.notification_target
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment