mirror of
https://github.com/ghndrx/terraform-foundation.git
synced 2026-02-10 06:45:06 +00:00
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
291 lines
7.3 KiB
HCL
291 lines
7.3 KiB
HCL
################################################################################
|
|
# KMS Key Module
|
|
#
|
|
# Customer-managed KMS keys for encryption:
|
|
# - Automatic key rotation
|
|
# - Cross-account access
|
|
# - Service-specific grants
|
|
# - Alias management
|
|
# - Key policies
|
|
#
|
|
# Usage:
|
|
# module "kms" {
|
|
# source = "../modules/kms-key"
|
|
#
|
|
# name = "myapp-encryption"
|
|
# description = "Encryption key for myapp"
|
|
#
|
|
# service_principals = ["logs.amazonaws.com", "s3.amazonaws.com"]
|
|
# }
|
|
################################################################################
|
|
|
|
terraform {
|
|
required_providers {
|
|
aws = {
|
|
source = "hashicorp/aws"
|
|
version = ">= 5.0"
|
|
}
|
|
}
|
|
}
|
|
|
|
variable "name" {
|
|
type = string
|
|
description = "Key name (used for alias)"
|
|
}
|
|
|
|
variable "description" {
|
|
type = string
|
|
default = ""
|
|
description = "Key description"
|
|
}
|
|
|
|
variable "deletion_window_in_days" {
|
|
type = number
|
|
default = 30
|
|
description = "Waiting period before key deletion (7-30 days)"
|
|
|
|
validation {
|
|
condition = var.deletion_window_in_days >= 7 && var.deletion_window_in_days <= 30
|
|
error_message = "Must be between 7 and 30 days"
|
|
}
|
|
}
|
|
|
|
variable "enable_key_rotation" {
|
|
type = bool
|
|
default = true
|
|
description = "Enable automatic key rotation (annual)"
|
|
}
|
|
|
|
variable "multi_region" {
|
|
type = bool
|
|
default = false
|
|
description = "Create a multi-region key"
|
|
}
|
|
|
|
variable "key_usage" {
|
|
type = string
|
|
default = "ENCRYPT_DECRYPT"
|
|
description = "Key usage: ENCRYPT_DECRYPT or SIGN_VERIFY"
|
|
|
|
validation {
|
|
condition = contains(["ENCRYPT_DECRYPT", "SIGN_VERIFY", "GENERATE_VERIFY_MAC"], var.key_usage)
|
|
error_message = "Must be ENCRYPT_DECRYPT, SIGN_VERIFY, or GENERATE_VERIFY_MAC"
|
|
}
|
|
}
|
|
|
|
variable "key_spec" {
|
|
type = string
|
|
default = "SYMMETRIC_DEFAULT"
|
|
description = "Key spec (SYMMETRIC_DEFAULT, RSA_2048, ECC_NIST_P256, etc.)"
|
|
}
|
|
|
|
variable "admin_principals" {
|
|
type = list(string)
|
|
default = []
|
|
description = "IAM ARNs with full admin access to the key"
|
|
}
|
|
|
|
variable "user_principals" {
|
|
type = list(string)
|
|
default = []
|
|
description = "IAM ARNs with encrypt/decrypt access"
|
|
}
|
|
|
|
variable "service_principals" {
|
|
type = list(string)
|
|
default = []
|
|
description = "AWS service principals that can use the key (e.g., logs.amazonaws.com)"
|
|
}
|
|
|
|
variable "grant_accounts" {
|
|
type = list(string)
|
|
default = []
|
|
description = "Account IDs with cross-account access"
|
|
}
|
|
|
|
variable "tags" {
|
|
type = map(string)
|
|
default = {}
|
|
}
|
|
|
|
################################################################################
|
|
# Data Sources
|
|
################################################################################
|
|
|
|
data "aws_caller_identity" "current" {}
|
|
data "aws_region" "current" {}
|
|
|
|
################################################################################
|
|
# KMS Key
|
|
################################################################################
|
|
|
|
resource "aws_kms_key" "main" {
|
|
description = var.description != "" ? var.description : "KMS key for ${var.name}"
|
|
deletion_window_in_days = var.deletion_window_in_days
|
|
enable_key_rotation = var.key_spec == "SYMMETRIC_DEFAULT" ? var.enable_key_rotation : false
|
|
multi_region = var.multi_region
|
|
key_usage = var.key_usage
|
|
customer_master_key_spec = var.key_spec
|
|
|
|
policy = jsonencode({
|
|
Version = "2012-10-17"
|
|
Statement = concat(
|
|
# Root account access (required)
|
|
[{
|
|
Sid = "EnableRootPermissions"
|
|
Effect = "Allow"
|
|
Principal = {
|
|
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
|
|
}
|
|
Action = "kms:*"
|
|
Resource = "*"
|
|
}],
|
|
|
|
# Admin principals
|
|
length(var.admin_principals) > 0 ? [{
|
|
Sid = "KeyAdministrators"
|
|
Effect = "Allow"
|
|
Principal = {
|
|
AWS = var.admin_principals
|
|
}
|
|
Action = [
|
|
"kms:Create*",
|
|
"kms:Describe*",
|
|
"kms:Enable*",
|
|
"kms:List*",
|
|
"kms:Put*",
|
|
"kms:Update*",
|
|
"kms:Revoke*",
|
|
"kms:Disable*",
|
|
"kms:Get*",
|
|
"kms:Delete*",
|
|
"kms:TagResource",
|
|
"kms:UntagResource",
|
|
"kms:ScheduleKeyDeletion",
|
|
"kms:CancelKeyDeletion"
|
|
]
|
|
Resource = "*"
|
|
}] : [],
|
|
|
|
# User principals
|
|
length(var.user_principals) > 0 ? [{
|
|
Sid = "KeyUsers"
|
|
Effect = "Allow"
|
|
Principal = {
|
|
AWS = var.user_principals
|
|
}
|
|
Action = [
|
|
"kms:Encrypt",
|
|
"kms:Decrypt",
|
|
"kms:ReEncrypt*",
|
|
"kms:GenerateDataKey*",
|
|
"kms:DescribeKey"
|
|
]
|
|
Resource = "*"
|
|
}] : [],
|
|
|
|
# Service principals
|
|
length(var.service_principals) > 0 ? [{
|
|
Sid = "AllowServices"
|
|
Effect = "Allow"
|
|
Principal = {
|
|
Service = var.service_principals
|
|
}
|
|
Action = [
|
|
"kms:Encrypt",
|
|
"kms:Decrypt",
|
|
"kms:ReEncrypt*",
|
|
"kms:GenerateDataKey*",
|
|
"kms:DescribeKey"
|
|
]
|
|
Resource = "*"
|
|
Condition = {
|
|
StringEquals = {
|
|
"aws:SourceAccount" = data.aws_caller_identity.current.account_id
|
|
}
|
|
}
|
|
}] : [],
|
|
|
|
# Cross-account access
|
|
length(var.grant_accounts) > 0 ? [{
|
|
Sid = "CrossAccountAccess"
|
|
Effect = "Allow"
|
|
Principal = {
|
|
AWS = [for acct in var.grant_accounts : "arn:aws:iam::${acct}:root"]
|
|
}
|
|
Action = [
|
|
"kms:Encrypt",
|
|
"kms:Decrypt",
|
|
"kms:ReEncrypt*",
|
|
"kms:GenerateDataKey*",
|
|
"kms:DescribeKey"
|
|
]
|
|
Resource = "*"
|
|
}] : [],
|
|
|
|
# Allow grants (needed for some AWS services)
|
|
[{
|
|
Sid = "AllowGrants"
|
|
Effect = "Allow"
|
|
Principal = {
|
|
AWS = concat(
|
|
["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"],
|
|
var.user_principals
|
|
)
|
|
}
|
|
Action = [
|
|
"kms:CreateGrant",
|
|
"kms:ListGrants",
|
|
"kms:RevokeGrant"
|
|
]
|
|
Resource = "*"
|
|
Condition = {
|
|
Bool = {
|
|
"kms:GrantIsForAWSResource" = "true"
|
|
}
|
|
}
|
|
}]
|
|
)
|
|
})
|
|
|
|
tags = merge(var.tags, { Name = var.name })
|
|
}
|
|
|
|
################################################################################
|
|
# Alias
|
|
################################################################################
|
|
|
|
resource "aws_kms_alias" "main" {
|
|
name = "alias/${var.name}"
|
|
target_key_id = aws_kms_key.main.key_id
|
|
}
|
|
|
|
################################################################################
|
|
# Outputs
|
|
################################################################################
|
|
|
|
output "key_id" {
|
|
value = aws_kms_key.main.key_id
|
|
description = "KMS key ID"
|
|
}
|
|
|
|
output "key_arn" {
|
|
value = aws_kms_key.main.arn
|
|
description = "KMS key ARN"
|
|
}
|
|
|
|
output "alias_arn" {
|
|
value = aws_kms_alias.main.arn
|
|
description = "KMS alias ARN"
|
|
}
|
|
|
|
output "alias_name" {
|
|
value = aws_kms_alias.main.name
|
|
description = "KMS alias name"
|
|
}
|
|
|
|
output "key_policy" {
|
|
value = aws_kms_key.main.policy
|
|
description = "Key policy document"
|
|
}
|