Skip to content

Commit 3635a3f

Browse files
authored
feat: MSK serverless cluster (#28)
1 parent 6e76787 commit 3635a3f

File tree

8 files changed

+271
-0
lines changed

8 files changed

+271
-0
lines changed

examples/serverless/main.tf

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
provider "aws" {
2+
region = local.region
3+
}
4+
5+
data "aws_availability_zones" "available" {}
6+
7+
locals {
8+
name = "ex-${basename(path.cwd)}"
9+
region = "us-east-1"
10+
11+
vpc_cidr = "10.0.0.0/16"
12+
azs = slice(data.aws_availability_zones.available.names, 0, 3)
13+
14+
tags = {
15+
Example = local.name
16+
GithubRepo = "terraform-aws-msk-kafka-cluster"
17+
GithubOrg = "terraform-aws-modules"
18+
}
19+
}
20+
21+
module "msk_serverless_cluster" {
22+
source = "../../modules/serverless"
23+
24+
name = local.name
25+
26+
security_group_ids = [module.security_group.security_group_id]
27+
subnet_ids = module.vpc.private_subnets
28+
29+
create_cluster_policy = true
30+
cluster_policy_statements = {
31+
firehose = {
32+
sid = "firehose"
33+
principals = [
34+
{
35+
type = "Service"
36+
identifiers = ["firehose.amazonaws.com"]
37+
}
38+
]
39+
actions = [
40+
"kafka:CreateVpcConnection",
41+
"kafka:GetBootstrapBrokers",
42+
"kafka:DescribeClusterV2"
43+
]
44+
}
45+
}
46+
47+
tags = local.tags
48+
}
49+
50+
################################################################################
51+
# Supporting Resources
52+
################################################################################
53+
54+
module "vpc" {
55+
source = "terraform-aws-modules/vpc/aws"
56+
version = "~> 5.0"
57+
58+
name = local.name
59+
cidr = local.vpc_cidr
60+
61+
azs = local.azs
62+
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)]
63+
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)]
64+
database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)]
65+
66+
create_database_subnet_group = true
67+
enable_nat_gateway = true
68+
single_nat_gateway = true
69+
70+
tags = local.tags
71+
}
72+
73+
module "security_group" {
74+
source = "terraform-aws-modules/security-group/aws"
75+
version = "~> 5.0"
76+
77+
name = local.name
78+
description = "Security group for ${local.name}"
79+
vpc_id = module.vpc.vpc_id
80+
81+
ingress_cidr_blocks = module.vpc.private_subnets_cidr_blocks
82+
ingress_rules = [
83+
"kafka-broker-sasl-iam-tcp"
84+
]
85+
86+
tags = local.tags
87+
}

examples/serverless/outputs.tf

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
output "serverless_arn" {
2+
description = "The ARN of the serverless cluster"
3+
value = module.msk_serverless_cluster.serverless_arn
4+
}
5+
6+
output "serverless_cluster_uuid" {
7+
description = "UUID of the serverless cluster, for use in IAM policies"
8+
value = module.msk_serverless_cluster.serverless_cluster_uuid
9+
}

examples/serverless/variables.tf

Whitespace-only changes.

examples/serverless/versions.tf

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = ">= 5.21"
8+
}
9+
}
10+
}

modules/serverless/main.tf

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
################################################################################
2+
# Serverless Cluster
3+
################################################################################
4+
resource "aws_msk_serverless_cluster" "this" {
5+
count = var.create ? 1 : 0
6+
7+
client_authentication {
8+
sasl {
9+
iam {
10+
enabled = true
11+
}
12+
}
13+
}
14+
15+
cluster_name = var.name
16+
17+
vpc_config {
18+
security_group_ids = var.security_group_ids
19+
subnet_ids = var.subnet_ids
20+
}
21+
22+
tags = var.tags
23+
}
24+
25+
################################################################################
26+
# Cluster Policy
27+
################################################################################
28+
29+
resource "aws_msk_cluster_policy" "this" {
30+
count = var.create && var.create_cluster_policy ? 1 : 0
31+
32+
cluster_arn = aws_msk_serverless_cluster.this[0].arn
33+
policy = data.aws_iam_policy_document.this[0].json
34+
}
35+
36+
data "aws_iam_policy_document" "this" {
37+
count = var.create && var.create_cluster_policy ? 1 : 0
38+
39+
source_policy_documents = var.cluster_source_policy_documents
40+
override_policy_documents = var.cluster_override_policy_documents
41+
42+
dynamic "statement" {
43+
for_each = var.cluster_policy_statements
44+
45+
content {
46+
sid = try(statement.value.sid, null)
47+
actions = try(statement.value.actions, null)
48+
not_actions = try(statement.value.not_actions, null)
49+
effect = try(statement.value.effect, null)
50+
resources = try(statement.value.resources, [aws_msk_serverless_cluster.this[0].arn])
51+
not_resources = try(statement.value.not_resources, null)
52+
53+
dynamic "principals" {
54+
for_each = try(statement.value.principals, [])
55+
56+
content {
57+
type = principals.value.type
58+
identifiers = principals.value.identifiers
59+
}
60+
}
61+
62+
dynamic "not_principals" {
63+
for_each = try(statement.value.not_principals, [])
64+
65+
content {
66+
type = not_principals.value.type
67+
identifiers = not_principals.value.identifiers
68+
}
69+
}
70+
71+
dynamic "condition" {
72+
for_each = try(statement.value.conditions, [])
73+
74+
content {
75+
test = condition.value.test
76+
values = condition.value.values
77+
variable = condition.value.variable
78+
}
79+
}
80+
}
81+
}
82+
}

modules/serverless/outputs.tf

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
################################################################################
2+
# Serverless Cluster
3+
################################################################################
4+
5+
output "serverless_arn" {
6+
description = "The ARN of the serverless cluster"
7+
value = try(aws_msk_serverless_cluster.this[0].arn, null)
8+
}
9+
10+
output "serverless_cluster_uuid" {
11+
description = "UUID of the serverless cluster, for use in IAM policies"
12+
value = try(aws_msk_serverless_cluster.this[0].cluster_uuid, null)
13+
}

modules/serverless/variables.tf

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
################################################################################
2+
# Serverless Cluster
3+
################################################################################
4+
variable "create" {
5+
description = "Determines whether cluster resources will be created"
6+
type = bool
7+
default = true
8+
}
9+
10+
variable "name" {
11+
description = "Name of the MSK serverless cluster"
12+
type = string
13+
default = null
14+
}
15+
16+
variable "security_group_ids" {
17+
description = "Specifies up to five security groups that control inbound and outbound traffic for the serverless cluster"
18+
type = list(string)
19+
default = null
20+
}
21+
22+
variable "subnet_ids" {
23+
description = "A list of subnets in at least two different Availability Zones that host your client applications"
24+
type = list(string)
25+
default = null
26+
}
27+
28+
variable "tags" {
29+
description = "A map of tags to assign to the resources created"
30+
type = map(string)
31+
default = {}
32+
}
33+
34+
################################################################################
35+
# Cluster Policy
36+
################################################################################
37+
38+
variable "create_cluster_policy" {
39+
description = "Determines whether to create an MSK cluster policy"
40+
type = bool
41+
default = false
42+
}
43+
44+
variable "cluster_source_policy_documents" {
45+
description = "Source policy documents for cluster policy"
46+
type = list(string)
47+
default = null
48+
}
49+
50+
variable "cluster_override_policy_documents" {
51+
description = "Override policy documents for cluster policy"
52+
type = list(string)
53+
default = null
54+
}
55+
56+
variable "cluster_policy_statements" {
57+
description = "Map of policy statements for cluster policy"
58+
type = any
59+
default = null
60+
}

modules/serverless/versions.tf

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = ">= 5.21"
8+
}
9+
}
10+
}

0 commit comments

Comments
 (0)