Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(kms): Add support for kms key rotation #133

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ test.py
.idea

**/wandb/*
policy.json
policy.json
results.json
4 changes: 2 additions & 2 deletions .tflint.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ config {

plugin "aws" {
enabled = true
version = "0.7.2"
version = "0.26.0"
source = "github.com/terraform-linters/tflint-ruleset-aws"
}
}
28 changes: 28 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.DEFAULT_GOAL := help

.PHONY: format
format: ## Terraform Format
terraform fmt --recursive

.PHONY: lint
lint: ## Terraform lint
tflint --init --recursive --config .tflint.hcl

.PHONY: docs
docs: ## Update terraform docs
terraform-docs -c .terraform-docs.yml . --recursive

.PHONY: sast
sast: ## Run SAST scan on terraform
docker run -t -v ${PWD}:/path checkmarx/kics:latest scan -p /path -o "/path/"

.PHONY: help
help: ## Shows all targets and help from the Makefile (this message).
@grep --no-filename -E '^([a-z.A-Z_%-/]+:.*?)##' $(MAKEFILE_LIST) | sort | \
awk 'BEGIN {FS = ":.*?(## ?)"}; { \
if (length($$1) > 0) { \
printf " \033[36m%-30s\033[0m %s\n", $$1, $$2; \
} else { \
printf "%s\n", $$2; \
} \
}'
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,15 @@ Upgrades must be executed in step-wise fashion from one version to the next. You

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 4.6 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 1.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 4.0 |
| <a name="requirement_kubernetes"></a> [kubernetes](#requirement\_kubernetes) | ~> 2.6 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 4.6 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | 4.67.0 |

## Modules

Expand Down Expand Up @@ -157,26 +157,23 @@ Upgrades must be executed in step-wise fashion from one version to the next. You
| <a name="input_create_bucket"></a> [create\_bucket](#input\_create\_bucket) | ######################################### External Bucket # ######################################### Most users will not need these settings. They are ment for users who want a bucket and sqs that are in a different account. | `bool` | `true` | no |
| <a name="input_create_elasticache"></a> [create\_elasticache](#input\_create\_elasticache) | Boolean indicating whether to provision an elasticache instance (true) or not (false). | `bool` | `true` | no |
| <a name="input_create_vpc"></a> [create\_vpc](#input\_create\_vpc) | Boolean indicating whether to deploy a VPC (true) or not (false). | `bool` | `true` | no |
| <a name="input_database_binlog_format"></a> [database\_binlog\_format](#input\_database\_binlog\_format) | Specifies the binlog\_format value to set for the database | `string` | `"ROW"` | no |
| <a name="input_database_engine_version"></a> [database\_engine\_version](#input\_database\_engine\_version) | Version for MySQL Auora | `string` | `"8.0.mysql_aurora.3.03.0"` | no |
| <a name="input_database_innodb_lru_scan_depth"></a> [database\_innodb\_lru\_scan\_depth](#input\_database\_innodb\_lru\_scan\_depth) | Specifies the innodb\_lru\_scan\_depth value to set for the database | `number` | `128` | no |
| <a name="input_database_instance_class"></a> [database\_instance\_class](#input\_database\_instance\_class) | Instance type to use by database master instance. | `string` | `"db.r5.large"` | no |
| <a name="input_database_master_username"></a> [database\_master\_username](#input\_database\_master\_username) | Specifies the master\_username value to set for the database | `string` | `"wandb"` | no |
| <a name="input_database_name"></a> [database\_name](#input\_database\_name) | Specifies the name of the database | `string` | `"wandb_local"` | no |
| <a name="input_database_performance_insights_kms_key_arn"></a> [database\_performance\_insights\_kms\_key\_arn](#input\_database\_performance\_insights\_kms\_key\_arn) | Specifies an existing KMS key ARN to encrypt the performance insights data if performance\_insights\_enabled is was enabled out of band | `string` | n/a | yes |
| <a name="input_database_performance_insights_kms_key_arn"></a> [database\_performance\_insights\_kms\_key\_arn](#input\_database\_performance\_insights\_kms\_key\_arn) | Specifies an existing KMS key ARN to encrypt the performance insights data if performance\_insights\_enabled is was enabled out of band | `string` | `null` | no |
| <a name="input_database_snapshot_identifier"></a> [database\_snapshot\_identifier](#input\_database\_snapshot\_identifier) | Specifies whether or not to create this cluster from a snapshot. You can use either the name or ARN when specifying a DB cluster snapshot, or the ARN when specifying a DB snapshot | `string` | `null` | no |
| <a name="input_database_sort_buffer_size"></a> [database\_sort\_buffer\_size](#input\_database\_sort\_buffer\_size) | Specifies the sort\_buffer\_size value to set for the database | `number` | `67108864` | no |
| <a name="input_deletion_protection"></a> [deletion\_protection](#input\_deletion\_protection) | If the instance should have deletion protection enabled. The database / S3 can't be deleted when this value is set to `true`. | `bool` | `true` | no |
| <a name="input_domain_name"></a> [domain\_name](#input\_domain\_name) | Domain for accessing the Weights & Biases UI. | `string` | n/a | yes |
| <a name="input_eks_cluster_version"></a> [eks\_cluster\_version](#input\_eks\_cluster\_version) | Indicates EKS cluster version | `string` | `"1.21"` | no |
| <a name="input_eks_policy_arns"></a> [eks\_policy\_arns](#input\_eks\_policy\_arns) | Additional IAM policy to apply to the EKS cluster | `list(string)` | `[]` | no |
| <a name="input_eks_cluster_version"></a> [eks\_cluster\_version](#input\_eks\_cluster\_version) | EKS cluster kubernetes version | `string` | n/a | yes |
| <a name="input_elasticache_node_type"></a> [elasticache\_node\_type](#input\_elasticache\_node\_type) | The type of the redis cache node to deploy | `string` | `"cache.t2.medium"` | no |
| <a name="input_external_dns"></a> [external\_dns](#input\_external\_dns) | Using external DNS. A `subdomain` must also be specified if this value is true. | `bool` | `false` | no |
| <a name="input_extra_fqdn"></a> [extra\_fqdn](#input\_extra\_fqdn) | n/a | `list(string)` | `[]` | no |
| <a name="input_kms_key_alias"></a> [kms\_key\_alias](#input\_kms\_key\_alias) | KMS key alias for AWS KMS Customer managed key. | `string` | `null` | no |
| <a name="input_kms_key_deletion_window"></a> [kms\_key\_deletion\_window](#input\_kms\_key\_deletion\_window) | Duration in days to destroy the key after it is deleted. Must be between 7 and 30 days. | `number` | `7` | no |
| <a name="input_kms_key_policy"></a> [kms\_key\_policy](#input\_kms\_key\_policy) | The policy that will define the permissions for the kms key. | `string` | `""` | no |
| <a name="input_kubernetes_instance_types"></a> [kubernetes\_instance\_types](#input\_kubernetes\_instance\_types) | EC2 Instance type for primary node group. | `list(string)` | <pre>[<br> "m4.large"<br>]</pre> | no |
| <a name="input_kubernetes_instance_types"></a> [kubernetes\_instance\_types](#input\_kubernetes\_instance\_types) | EC2 Instance type for primary node group. | `list(string)` | <pre>[<br> "m5.large"<br>]</pre> | no |
| <a name="input_kubernetes_map_accounts"></a> [kubernetes\_map\_accounts](#input\_kubernetes\_map\_accounts) | Additional AWS account numbers to add to the aws-auth configmap. | `list(string)` | `[]` | no |
| <a name="input_kubernetes_map_roles"></a> [kubernetes\_map\_roles](#input\_kubernetes\_map\_roles) | Additional IAM roles to add to the aws-auth configmap. | <pre>list(object({<br> rolearn = string<br> username = string<br> groups = list(string)<br> }))</pre> | `[]` | no |
| <a name="input_kubernetes_map_users"></a> [kubernetes\_map\_users](#input\_kubernetes\_map\_users) | Additional IAM users to add to the aws-auth configmap. | <pre>list(object({<br> userarn = string<br> username = string<br> groups = list(string)<br> }))</pre> | `[]` | no |
Expand Down
2 changes: 1 addition & 1 deletion examples/public-dns-external/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module "wandb_infra" {
database_sort_buffer_size = var.database_sort_buffer_size

allowed_inbound_cidr = var.allowed_inbound_cidr
allowed_inbound_ipv6_cidr = ["::/0"]
allowed_inbound_ipv6_cidr = var.allowed_inbound_ipv6_cidr

eks_cluster_version = "1.25"
kubernetes_public_access = true
Expand Down
13 changes: 6 additions & 7 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ module "file_storage" {
}

locals {
bucket_name = local.use_external_bucket ? var.bucket_name : module.file_storage.0.bucket_name
bucket_queue_name = local.use_internal_queue ? null : module.file_storage.0.bucket_queue_name
bucket_name = local.use_external_bucket ? var.bucket_name : module.file_storage[0].bucket_name
bucket_queue_name = local.use_internal_queue ? null : module.file_storage[0].bucket_queue_name
}

module "networking" {
Expand All @@ -39,7 +39,7 @@ module "networking" {
cidr = var.network_cidr
private_subnet_cidrs = var.network_private_subnet_cidrs
public_subnet_cidrs = var.network_public_subnet_cidrs
database_subnet_cidrs = var.network_database_subnet_cidrs
database_subnet_cidrs = local.network_database_subnet_cidrs
create_elasticache_subnet = var.create_elasticache
elasticache_subnet_cidrs = var.network_elasticache_subnet_cidrs
}
Expand Down Expand Up @@ -125,7 +125,7 @@ module "app_eks" {

bucket_kms_key_arn = local.use_external_bucket ? var.bucket_kms_key_arn : local.kms_key_arn
bucket_arn = data.aws_s3_bucket.file_storage.arn
bucket_sqs_queue_arn = local.use_internal_queue ? null : data.aws_sqs_queue.file_storage.0.arn
bucket_sqs_queue_arn = local.use_internal_queue ? null : data.aws_sqs_queue.file_storage[0].arn

network_id = local.network_id
network_private_subnets = local.network_private_subnets
Expand All @@ -134,13 +134,11 @@ module "app_eks" {
database_security_group_id = module.database.security_group_id

create_elasticache_security_group = var.create_elasticache
elasticache_security_group_id = var.create_elasticache ? module.redis.0.security_group_id : null
elasticache_security_group_id = var.create_elasticache ? module.redis[0].security_group_id : null

cluster_version = var.eks_cluster_version
cluster_endpoint_public_access = var.kubernetes_public_access
cluster_endpoint_public_access_cidrs = var.kubernetes_public_access_cidrs

eks_policy_arns = var.eks_policy_arns
}

module "app_lb" {
Expand All @@ -160,6 +158,7 @@ module "app_lb" {
network_id = local.network_id
network_private_subnets = local.network_private_subnets
network_public_subnets = local.network_public_subnets
ssl_policy = var.ssl_policy
}

resource "aws_autoscaling_attachment" "autoscaling_attachment" {
Expand Down
2 changes: 1 addition & 1 deletion modules/app_eks/iam-policy-docs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ data "aws_iam_policy_document" "node_s3" {
actions = ["s3:*"]
effect = "Allow"
resources = [
"${var.bucket_arn}",
var.bucket_arn,
"${var.bucket_arn}/*"
]
}
Expand Down
8 changes: 0 additions & 8 deletions modules/app_eks/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,6 @@ resource "aws_eks_addon" "eks" {
]
}

locals {
managed_policy_arns = concat([
"arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy",
"arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy",
"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly",
], var.eks_policy_arns)
}

module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 17.23"
Expand Down
7 changes: 0 additions & 7 deletions modules/app_eks/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ variable "database_security_group_id" {
type = string
}

variable "eks_policy_arns" {
description = "Additional IAM policy to apply to the EKS cluster"
type = list(string)
default = []
}

variable "elasticache_security_group_id" {
type = string
default = null
Expand Down Expand Up @@ -111,4 +105,3 @@ variable "service_port" {
type = number
default = 32543
}

4 changes: 2 additions & 2 deletions modules/database/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ module "aurora" {
enabled_cloudwatch_logs_exports = ["audit", "error", "general", "slowquery"]
engine = "aurora-mysql"
engine_version = var.engine_version
iam_database_authentication_enabled = false
iam_database_authentication_enabled = var.iam_database_authentication_enabled
iam_role_force_detach_policies = true
iam_role_name = "${var.namespace}-aurora-monitoring"
instance_class = var.instance_class
Expand All @@ -134,7 +134,7 @@ module "aurora" {
performance_insights_retention_period = 7
preferred_backup_window = var.preferred_backup_window
preferred_maintenance_window = var.preferred_maintenance_window
security_group_tags = { "Namespace" : "${var.namespace}" }
security_group_tags = { "Namespace" : var.namespace }
skip_final_snapshot = true
snapshot_identifier = var.snapshot_identifier
storage_encrypted = true
Expand Down
2 changes: 1 addition & 1 deletion modules/database/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ variable "preferred_maintenance_window" {
variable "iam_database_authentication_enabled" {
description = "Specifies whether or mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled"
type = bool
default = true
default = false
}

variable "allowed_cidr_blocks" {
Expand Down
8 changes: 4 additions & 4 deletions modules/file_storage/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "file_storage" {
resource "aws_sqs_queue_policy" "file_storage" {
count = var.create_queue && var.create_queue_policy ? 1 : 0

queue_url = aws_sqs_queue.file_storage.0.id
queue_url = aws_sqs_queue.file_storage[0].id

policy = jsonencode({
"Version" : "2012-10-17",
Expand All @@ -84,9 +84,9 @@ resource "aws_sqs_queue_policy" "file_storage" {
"Effect" : "Allow",
"Principal" : "*",
"Action" : ["sqs:SendMessage"],
"Resource" : "arn:aws:sqs:*:*:${aws_sqs_queue.file_storage.0.name}",
"Resource" : "arn:aws:sqs:*:*:${aws_sqs_queue.file_storage[0].name}",
"Condition" : {
"ArnEquals" : { "aws:SourceArn" : "${aws_s3_bucket.file_storage.arn}" }
"ArnEquals" : { "aws:SourceArn" : aws_s3_bucket.file_storage.arn }
}
}
]
Expand All @@ -101,7 +101,7 @@ resource "aws_s3_bucket_notification" "file_storage" {
bucket = aws_s3_bucket.file_storage.id

queue {
queue_arn = aws_sqs_queue.file_storage.0.arn
queue_arn = aws_sqs_queue.file_storage[0].arn
events = ["s3:ObjectCreated:*"]
}
}
6 changes: 3 additions & 3 deletions modules/file_storage/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ output "bucket_region" {
}

output "bucket_queue_name" {
value = var.create_queue ? aws_sqs_queue.file_storage.0.name : null
value = var.create_queue ? aws_sqs_queue.file_storage[0].name : null
}

output "bucket_queue_arn" {
value = var.create_queue ? aws_sqs_queue.file_storage.0.arn : null
}
value = var.create_queue ? aws_sqs_queue.file_storage[0].arn : null
}
5 changes: 3 additions & 2 deletions modules/kms/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ resource "aws_kms_key" "key" {
deletion_window_in_days = var.key_deletion_window
description = "AWS KMS Customer-managed key to encrypt Weights & Biases resources"
key_usage = "ENCRYPT_DECRYPT"
enable_key_rotation = var.enable_key_rotation

policy = var.key_policy != "" ? var.key_policy : jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Sid" : "Allow administration of the key",
"Effect" : "Allow",
"Principal" : { "AWS" : "${data.aws_caller_identity.current.arn}" },
"Principal" : { "AWS" : data.aws_caller_identity.current.arn },
"Action" : "kms:*",
"Resource" : "*"
},
Expand Down Expand Up @@ -52,7 +53,7 @@ resource "aws_kms_key" "key" {
"Resource" : "*",
"Condition" : {
"StringEquals" : {
"kms:CallerAccount" : "${data.aws_caller_identity.current.account_id}",
"kms:CallerAccount" : data.aws_caller_identity.current.account_id,
},
"StringLike" : {
"kms:ViaService" : "ec2.*.amazonaws.com",
Expand Down
8 changes: 7 additions & 1 deletion modules/kms/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ variable "key_deletion_window" {
type = number
}

variable "enable_key_rotation" {
description = "Specifies whether key rotation is enabled. https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html"
type = bool
default = true
}

variable "iam_principal_arn" {
description = "The IAM principal (role or user) ARN that will be authorized to use the key."
type = string
Expand All @@ -18,4 +24,4 @@ variable "key_policy" {
description = "The policy that will define the permissions for the kms key."
type = string
default = ""
}
}
1 change: 1 addition & 0 deletions modules/networking/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module "vpc" {

create_vpc = var.create_vpc

amazon_side_asn = var.amazon_side_asn
azs = data.aws_availability_zones.available.names
cidr = var.cidr
create_igw = true
Expand Down
Loading
Loading