mirror of
https://github.com/ghndrx/terraform-foundation.git
synced 2026-02-10 06:45:06 +00:00
feat: Terraform Foundation - AWS Landing Zone
Enterprise-grade multi-tenant AWS cloud foundation. Modules: - GitHub OIDC for keyless CI/CD authentication - IAM account settings and security baseline - AWS Config Rules for compliance - ABAC (Attribute-Based Access Control) - SCPs (Service Control Policies) Features: - Multi-account architecture - Cost optimization patterns - Security best practices - Comprehensive documentation Tech: Terraform, AWS Organizations, IAM Identity Center
This commit is contained in:
38
terraform/modules/tenant-budget/README.md
Normal file
38
terraform/modules/tenant-budget/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# tenant-budget
|
||||
|
||||
Terraform module for AWS landing zone pattern.
|
||||
|
||||
Create tenant-specific AWS budget alerts.
|
||||
|
||||
## Planned Features
|
||||
|
||||
- [ ] Monthly budget with configurable limit
|
||||
- [ ] Multi-threshold alerts (50%, 80%, 100%, 120%)
|
||||
- [ ] Cost allocation tag filtering
|
||||
- [ ] SNS and email notifications
|
||||
- [ ] Forecasted spend alerts
|
||||
- [ ] Auto-actions at budget limits (optional)
|
||||
|
||||
## Planned Usage
|
||||
|
||||
```hcl
|
||||
module "tenant_budget" {
|
||||
source = "../modules/tenant-budget"
|
||||
|
||||
tenant_name = "acme-corp"
|
||||
budget_limit = 500
|
||||
|
||||
alert_thresholds = [50, 80, 100]
|
||||
|
||||
notification_emails = [
|
||||
"billing@acme.com",
|
||||
"admin@acme.com"
|
||||
]
|
||||
|
||||
cost_filter_tags = {
|
||||
Tenant = "acme-corp"
|
||||
}
|
||||
|
||||
enable_forecasted_alerts = true
|
||||
}
|
||||
```
|
||||
144
terraform/modules/tenant-budget/main.tf
Normal file
144
terraform/modules/tenant-budget/main.tf
Normal file
@@ -0,0 +1,144 @@
|
||||
################################################################################
|
||||
# Tenant Budget Module
|
||||
#
|
||||
# Creates tenant-specific budget with alerts:
|
||||
# - Monthly budget with configurable limit
|
||||
# - Multi-threshold alerts
|
||||
# - Cost allocation tag filtering
|
||||
# - SNS and email notifications
|
||||
################################################################################
|
||||
|
||||
terraform {
|
||||
required_version = ">= 1.5.0"
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = ">= 5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data "aws_caller_identity" "current" {}
|
||||
|
||||
locals {
|
||||
account_id = data.aws_caller_identity.current.account_id
|
||||
|
||||
# Build cost filters from tags
|
||||
cost_filters = length(var.cost_filter_tags) > 0 ? {
|
||||
TagKeyValue = [for k, v in var.cost_filter_tags : "user:${k}$${v}"]
|
||||
} : {}
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# SNS Topic for Budget Alerts
|
||||
################################################################################
|
||||
|
||||
resource "aws_sns_topic" "budget" {
|
||||
count = var.create_sns_topic ? 1 : 0
|
||||
|
||||
name = "${var.name}-budget-alerts"
|
||||
|
||||
tags = merge(var.tags, {
|
||||
Name = "${var.name}-budget-alerts"
|
||||
})
|
||||
}
|
||||
|
||||
resource "aws_sns_topic_policy" "budget" {
|
||||
count = var.create_sns_topic ? 1 : 0
|
||||
|
||||
arn = aws_sns_topic.budget[0].arn
|
||||
|
||||
policy = jsonencode({
|
||||
Version = "2012-10-17"
|
||||
Statement = [
|
||||
{
|
||||
Sid = "AllowBudgetsPublish"
|
||||
Effect = "Allow"
|
||||
Principal = {
|
||||
Service = "budgets.amazonaws.com"
|
||||
}
|
||||
Action = "sns:Publish"
|
||||
Resource = aws_sns_topic.budget[0].arn
|
||||
Condition = {
|
||||
StringEquals = {
|
||||
"aws:SourceAccount" = local.account_id
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
resource "aws_sns_topic_subscription" "email" {
|
||||
for_each = var.create_sns_topic ? toset(var.notification_emails) : []
|
||||
|
||||
topic_arn = aws_sns_topic.budget[0].arn
|
||||
protocol = "email"
|
||||
endpoint = each.value
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Budget
|
||||
################################################################################
|
||||
|
||||
resource "aws_budgets_budget" "this" {
|
||||
name = "${var.name}-monthly-budget"
|
||||
budget_type = "COST"
|
||||
limit_amount = tostring(var.budget_limit)
|
||||
limit_unit = "USD"
|
||||
time_unit = "MONTHLY"
|
||||
|
||||
# Optional: Filter by cost allocation tags
|
||||
dynamic "cost_filter" {
|
||||
for_each = local.cost_filters
|
||||
content {
|
||||
name = cost_filter.key
|
||||
values = cost_filter.value
|
||||
}
|
||||
}
|
||||
|
||||
cost_types {
|
||||
include_credit = false
|
||||
include_discount = true
|
||||
include_other_subscription = true
|
||||
include_recurring = true
|
||||
include_refund = false
|
||||
include_subscription = true
|
||||
include_support = true
|
||||
include_tax = true
|
||||
include_upfront = true
|
||||
use_amortized = false
|
||||
use_blended = false
|
||||
}
|
||||
|
||||
# Actual spend notifications
|
||||
dynamic "notification" {
|
||||
for_each = var.alert_thresholds
|
||||
content {
|
||||
comparison_operator = "GREATER_THAN"
|
||||
threshold = notification.value
|
||||
threshold_type = "PERCENTAGE"
|
||||
notification_type = "ACTUAL"
|
||||
subscriber_email_addresses = var.create_sns_topic ? [] : var.notification_emails
|
||||
subscriber_sns_topic_arns = var.create_sns_topic ? [aws_sns_topic.budget[0].arn] : (var.sns_topic_arn != null ? [var.sns_topic_arn] : [])
|
||||
}
|
||||
}
|
||||
|
||||
# Forecasted spend notifications
|
||||
dynamic "notification" {
|
||||
for_each = var.enable_forecasted_alerts ? var.forecasted_thresholds : []
|
||||
content {
|
||||
comparison_operator = "GREATER_THAN"
|
||||
threshold = notification.value
|
||||
threshold_type = "PERCENTAGE"
|
||||
notification_type = "FORECASTED"
|
||||
subscriber_email_addresses = var.create_sns_topic ? [] : var.notification_emails
|
||||
subscriber_sns_topic_arns = var.create_sns_topic ? [aws_sns_topic.budget[0].arn] : (var.sns_topic_arn != null ? [var.sns_topic_arn] : [])
|
||||
}
|
||||
}
|
||||
|
||||
tags = merge(var.tags, {
|
||||
Name = "${var.name}-monthly-budget"
|
||||
Tenant = var.name
|
||||
})
|
||||
}
|
||||
28
terraform/modules/tenant-budget/outputs.tf
Normal file
28
terraform/modules/tenant-budget/outputs.tf
Normal file
@@ -0,0 +1,28 @@
|
||||
################################################################################
|
||||
# Tenant Budget - Outputs
|
||||
################################################################################
|
||||
|
||||
output "budget_id" {
|
||||
value = aws_budgets_budget.this.id
|
||||
description = "Budget ID"
|
||||
}
|
||||
|
||||
output "budget_name" {
|
||||
value = aws_budgets_budget.this.name
|
||||
description = "Budget name"
|
||||
}
|
||||
|
||||
output "budget_limit" {
|
||||
value = var.budget_limit
|
||||
description = "Budget limit in USD"
|
||||
}
|
||||
|
||||
output "sns_topic_arn" {
|
||||
value = var.create_sns_topic ? aws_sns_topic.budget[0].arn : var.sns_topic_arn
|
||||
description = "SNS topic ARN for budget alerts"
|
||||
}
|
||||
|
||||
output "alert_thresholds" {
|
||||
value = var.alert_thresholds
|
||||
description = "Configured alert thresholds"
|
||||
}
|
||||
61
terraform/modules/tenant-budget/variables.tf
Normal file
61
terraform/modules/tenant-budget/variables.tf
Normal file
@@ -0,0 +1,61 @@
|
||||
################################################################################
|
||||
# Tenant Budget - Input Variables
|
||||
################################################################################
|
||||
|
||||
variable "name" {
|
||||
type = string
|
||||
description = "Tenant/budget name"
|
||||
}
|
||||
|
||||
variable "budget_limit" {
|
||||
type = number
|
||||
description = "Monthly budget limit in USD"
|
||||
}
|
||||
|
||||
variable "alert_thresholds" {
|
||||
type = list(number)
|
||||
default = [50, 80, 100]
|
||||
description = "Percentage thresholds for actual spend alerts"
|
||||
}
|
||||
|
||||
variable "enable_forecasted_alerts" {
|
||||
type = bool
|
||||
default = true
|
||||
description = "Enable forecasted spend alerts"
|
||||
}
|
||||
|
||||
variable "forecasted_thresholds" {
|
||||
type = list(number)
|
||||
default = [100]
|
||||
description = "Percentage thresholds for forecasted spend alerts"
|
||||
}
|
||||
|
||||
variable "notification_emails" {
|
||||
type = list(string)
|
||||
default = []
|
||||
description = "Email addresses for budget alerts"
|
||||
}
|
||||
|
||||
variable "create_sns_topic" {
|
||||
type = bool
|
||||
default = true
|
||||
description = "Create SNS topic for alerts"
|
||||
}
|
||||
|
||||
variable "sns_topic_arn" {
|
||||
type = string
|
||||
default = null
|
||||
description = "Existing SNS topic ARN (if not creating)"
|
||||
}
|
||||
|
||||
variable "cost_filter_tags" {
|
||||
type = map(string)
|
||||
default = {}
|
||||
description = "Cost allocation tags to filter by"
|
||||
}
|
||||
|
||||
variable "tags" {
|
||||
type = map(string)
|
||||
default = {}
|
||||
description = "Tags to apply to resources"
|
||||
}
|
||||
Reference in New Issue
Block a user