Last active
January 5, 2024 11:02
Swatmobile - AWS Bootstrap gists
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
resource "aws_budgets_budget" "cloudwatch" { | |
provider = "aws.billing" | |
name = "budget-cloudwatch-monthly" | |
budget_type = "COST" | |
limit_amount = "1000" | |
limit_unit = "USD" | |
time_period_end = "2087-06-15_00:00" | |
time_period_start = "2017-07-01_00:00" | |
time_unit = "MONTHLY" | |
cost_filters = { | |
Service = "AmazonCloudWatch" | |
} | |
notification { | |
comparison_operator = "GREATER_THAN" | |
threshold = 100 | |
threshold_type = "PERCENTAGE" | |
notification_type = "FORECASTED" | |
subscriber_sns_topic_arns = [ | |
"${aws_sns_topic.budget_alerts.arn}", | |
] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
resource "aws_budgets_budget" "cloudwatch" { | |
provider = "aws.billing" | |
name = "budget-ec2-other-monthly" | |
budget_type = "COST" | |
limit_amount = "300" | |
limit_unit = "USD" | |
time_period_end = "2087-06-15_00:00" | |
time_period_start = "2017-07-01_00:00" | |
time_unit = "MONTHLY" | |
cost_filters = { | |
Service = "Amazon Elastic Block Store" | |
} | |
notification { | |
comparison_operator = "GREATER_THAN" | |
threshold = 100 | |
threshold_type = "PERCENTAGE" | |
notification_type = "FORECASTED" | |
subscriber_sns_topic_arns = [ | |
"${aws_sns_topic.budget_alerts.arn}", | |
] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# give AWS Budgets permissions to publish to budget_alerts sns topic | |
resource "aws_sns_topic_policy" "budget_alerts" { | |
provider = "aws.billing" | |
arn = "${aws_sns_topic.budget_alerts.arn}" | |
policy = "${data.aws_iam_policy_document.sns_budget_alerts.json}" | |
} | |
data "aws_iam_policy_document" "sns_budget_alerts" { | |
provider = "aws.billing" | |
policy_id = "__default_policy_ID" | |
statement { | |
sid = "AWSBudgetsAlerts" | |
principals { | |
type = "Service" | |
identifiers = ["budgets.amazonaws.com"] | |
} | |
actions = [ | |
"SNS:Publish", | |
] | |
resources = [ | |
"${aws_sns_topic.budget_alerts.arn}", | |
] | |
} | |
statement { | |
sid = "__default_statement_ID" | |
principals { | |
type = "AWS" | |
identifiers = ["*"] | |
} | |
actions = [ | |
"SNS:GetTopicAttributes", | |
"SNS:SetTopicAttributes", | |
"SNS:AddPermission", | |
"SNS:RemovePermission", | |
"SNS:DeleteTopic", | |
"SNS:Subscribe", | |
"SNS:ListSubscriptionsByTopic", | |
"SNS:Publish", | |
"SNS:Receive", | |
] | |
condition { | |
test = "StringEquals" | |
variable = "AWS:SourceOwner" | |
values = [ | |
"${data.aws_caller_identity.current.account_id}", | |
] | |
} | |
resources = [ | |
"${aws_sns_topic.budget_alerts.arn}", | |
] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# set up account wide budget alert for EstimatedCharges over billing_threshhold | |
module "swatmobile_budget_label" { | |
source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=master" | |
namespace = "swat" | |
stage = "svc" | |
name = "budget" | |
} | |
resource "aws_cloudwatch_metric_alarm" "account_billing" { | |
provider = "aws.billing" | |
alarm_name = "account-billing-alarm" | |
comparison_operator = "GreaterThanOrEqualToThreshold" | |
evaluation_periods = "1" # every 6 hours | |
period = "21600" # The period in seconds ~ 6 hours | |
metric_name = "EstimatedCharges" | |
namespace = "AWS/Billing" | |
statistic = "Average" | |
threshold = "${var.billing_threshhold}" | |
alarm_description = "Billing alarm by account" | |
alarm_actions = ["${aws_sns_topic.budget_alerts.arn}"] | |
dimensions { | |
Currency = "USD" | |
LinkedAccount = "${data.aws_caller_identity.current.account_id}" | |
} | |
} | |
resource "aws_sns_topic" "budget_alerts" { | |
provider = "aws.billing" | |
name = "${module.swatmobile_budget_label.id}-alerts" | |
tags = "${module.swatmobile_budget_label.tags}" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# CloudWatch billing alerts must be in US-EAST-1 | |
provider "aws" { | |
version = "~> 2.0" | |
region = "us-east-1" | |
alias = "billing" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
resource "aws_sns_topic_subscription" "billing_notify_slack" { | |
provider = "aws.billing" | |
topic_arn = "${aws_sns_topic.budget_alerts.arn}" | |
protocol = "lambda" | |
endpoint = "${aws_lambda_function.notify_slack.arn}" | |
} | |
resource "aws_lambda_permission" "billing_notify_slack" { | |
provider = "aws.billing" | |
statement_id = "AllowExecutionFromBudgetSNS" | |
action = "lambda:InvokeFunction" | |
function_name = "${aws_lambda_function.notify_slack.function_name}" | |
principal = "sns.amazonaws.com" | |
source_arn = "${aws_sns_topic.budget_alerts.arn}" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
resource "aws_iam_role" "lambda" { | |
provider = "aws.billing" | |
name_prefix = "lambda" | |
assume_role_policy = "${data.aws_iam_policy_document.assume_lambda_role.json}" | |
} | |
data "aws_iam_policy_document" "assume_lambda_role" { | |
statement { | |
effect = "Allow" | |
actions = ["sts:AssumeRole"] | |
principals { | |
type = "Service" | |
identifiers = ["lambda.amazonaws.com"] | |
} | |
} | |
} | |
# currently only CloudWatch rights granted | |
data "aws_iam_policy_document" "lambda_basic" { | |
statement { | |
sid = "AllowWriteToCloudwatchLogs" | |
effect = "Allow" | |
actions = [ | |
"logs:CreateLogGroup", | |
"logs:CreateLogStream", | |
"logs:PutLogEvents", | |
] | |
resources = ["arn:aws:logs:*:*:*"] | |
} | |
} | |
resource "aws_iam_role_policy" "lambda" { | |
provider = "aws.billing" | |
name_prefix = "lambda-policy-" | |
role = "${aws_iam_role.lambda.id}" | |
policy = "${data.aws_iam_policy_document.lambda_basic.json}" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module "swatmobile_notify_slack_label" { | |
source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=master" | |
namespace = "swat" | |
stage = "svc" | |
name = "notify-slack" | |
} | |
# add *.zip to .gitignore! | |
data "archive_file" "notify_slack" { | |
type = "zip" | |
source_file = "./functions/notify_slack.py" | |
output_path = "./functions/notify_slack.zip" | |
} | |
resource "aws_lambda_function" "notify_slack" { | |
provider = "aws.billing" | |
filename = "${data.archive_file.notify_slack.output_path}" | |
function_name = "${module.swatmobile_notify_slack_label.id}" | |
role = "${aws_iam_role.lambda.arn}" | |
handler = "notify_slack.lambda_handler" | |
source_code_hash = "${data.archive_file.notify_slack.output_base64sha256}" | |
runtime = "python3.6" | |
timeout = 30 | |
environment { | |
variables = { | |
SLACK_WEBHOOK_URL = "${var.notify_slack_webhook_url}" | |
SLACK_CHANNEL = "${var.notify_slack_channel}" | |
SLACK_USERNAME = "${var.notify_slack_username}" | |
SLACK_EMOJI = "${var.notify_slack_emoji}" | |
} | |
} | |
lifecycle { | |
ignore_changes = [ | |
"filename", | |
"last_modified", | |
] | |
} | |
tags = "${module.swatmobile_notify_slack_label.tags}" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
output "bucket" { | |
description = "The s3 bucket to use as Terraform Backend" | |
value = "${aws_s3_bucket.tfstate.id}" | |
} | |
output "lock_table" { | |
description = "The DynamoDb table for s3 backend locking" | |
value = "${aws_dynamodb_table.tfstate_lock.id}" | |
} | |
output "region" { | |
description = "The region used for remote state" | |
value = "${var.aws_region}" | |
} | |
output "kms_key_id" { | |
description = "kms key for encryption of state" | |
value = "${aws_kms_key.master.key_id}" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
terraform { | |
required_version = ">= 0.11" | |
version = "~1.17" | |
backend "s3" { | |
# A project specific key | |
key = "tf-remote-state/tfstate" # remember to choose unique key for each project | |
# team shared resources | |
bucket = "swat-tf-state" | |
region = "ap-southeast-1" | |
dynamodb_table = "swat-tf-state-lock" | |
encrypt = true # recommended to use encryption | |
kms_key_id = "1d3f..." | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
data "aws_caller_identity" "current" {} | |
resource "aws_iam_group" "tfusers" { | |
name = "${var.namespace}-${var.name}-tfusers" | |
} | |
resource "aws_iam_group_policy_attachment" "tfstate" { | |
group = "${aws_iam_group.tfusers.name}" | |
policy_arn = "${aws_iam_policy.tfstate.arn}" | |
} | |
resource "aws_iam_policy" "tfstate" { | |
name = "${var.namespace}-${var.name}-tfusers-policy" | |
description = "User policy managing access to Terraform state for ${var.name}" | |
policy = "${data.aws_iam_policy_document.tfstate.json}" | |
} | |
data "aws_iam_policy_document" "tfstate" { | |
# allow user to inspect himself | |
statement { | |
sid = "AllowSelfInspection" | |
actions = [ | |
"iam:GetUser", | |
] | |
resources = [ | |
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:user/$${aws:username}", | |
] | |
} | |
# allow listing of all buckets | |
statement { | |
sid = "ListS3Buckets" | |
actions = [ | |
"s3:ListAllMyBuckets", | |
] | |
resources = [ | |
"arn:aws:s3:::*", | |
] | |
} | |
# allow usage of kms key for decryption | |
statement { | |
sid = "KMSAccess" | |
# "Effect": "Allow", | |
actions = [ | |
"kms:Encrypt", | |
"kms:Decrypt", | |
"kms:GenerateDataKey", | |
] | |
resources = [ | |
"${aws_kms_key.master.arn}", | |
] | |
} | |
# allow all access to specific s3 tfsate buckets | |
statement { | |
sid = "AccessTerraformBuckets" | |
actions = [ | |
"s3:*", | |
] | |
resources = [ | |
"${aws_s3_bucket.tfstate.arn}", | |
"${aws_s3_bucket.tfstate.arn}/*", | |
] | |
} | |
# allow usage of lock table in dynamodb | |
# ref http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/using-identity-based-policies.html#access-policy-examples-for-sdk-cli | |
statement { | |
sid = "AllAPIActionsOnTerraformLocksTable" | |
actions = [ | |
"dynamodb:*", | |
] | |
resources = [ | |
"${aws_dynamodb_table.tfstate_lock.arn}", | |
"${aws_dynamodb_table.tfstate_lock.arn}/index/*", | |
] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
provider "aws" { | |
region = "${var.aws_region}" | |
} | |
module "swatmobile_state_label" { | |
source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=master" | |
namespace = "${var.namespace}" | |
stage = "${var.stage}" | |
name = "${var.name}" | |
} | |
resource "aws_s3_bucket" "tfstate" { | |
bucket = "${module.swatmobile_state_label.id}" | |
acl = "private" | |
versioning { | |
enabled = true | |
} | |
lifecycle { | |
prevent_destroy = true | |
} | |
tags = "${module.swatmobile_state_label.tags}" | |
} | |
resource "aws_kms_key" "master" { | |
description = "${module.swatmobile_state_label.id} master encryption key for Terraform state" | |
deletion_window_in_days = 10 | |
tags = "${module.swatmobile_state_label.tags}" | |
} | |
# allows ease of use on cli | |
resource "aws_kms_alias" "secrets" { | |
name = "alias/${module.swatmobile_state_label.id}-tfstate" | |
target_key_id = "${aws_kms_key.master.key_id}" | |
} | |
resource "aws_dynamodb_table" "tfstate_lock" { | |
name = "${module.swatmobile_state_label.id}-lock" | |
#http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughput.html | |
read_capacity = 1 | |
write_capacity = 1 | |
hash_key = "LockID" | |
attribute { | |
name = "LockID" | |
type = "S" # Attribute type, which must be a scalar type: (S)tring, (N)umber or (B)inary data | |
} | |
tags = "${module.swatmobile_state_label.tags}" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
variable "namespace" { | |
description = "Namespace for terraform state resources" | |
} | |
variable "stage" { | |
# We use: | |
# - Prod for production | |
# - Stage for staging | |
# - Dev for development | |
# - Svc for services (used across environments) | |
description = "Stage for terraform state resources" | |
} | |
variable "name" { | |
description = "Name for terraform state resources" | |
} | |
variable "aws_region" { | |
description = "The AWS region to create things in." | |
default = "ap-southeast-1" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment