Skip to content

Commit

Permalink
Refactors cross-account member for modern terraform syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
lorengordon committed Dec 27, 2024
1 parent f4b8441 commit 386a2bc
Show file tree
Hide file tree
Showing 13 changed files with 98 additions and 178 deletions.
4 changes: 2 additions & 2 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ locals {
"arn:${local.partition}:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.2.0",
]

partition = data.aws_partition.current.partition
region = data.aws_region.current.name
partition = data.aws_partition.current.partition
region = data.aws_region.current.name
}

data "aws_partition" "current" {}
Expand Down
34 changes: 0 additions & 34 deletions modules/accepter/README.md

This file was deleted.

3 changes: 0 additions & 3 deletions modules/accepter/main.tf

This file was deleted.

4 changes: 0 additions & 4 deletions modules/accepter/outputs.tf

This file was deleted.

4 changes: 0 additions & 4 deletions modules/accepter/variables.tf

This file was deleted.

10 changes: 0 additions & 10 deletions modules/accepter/versions.tf

This file was deleted.

36 changes: 15 additions & 21 deletions modules/cross-account-member/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,26 @@
module "account" {
source = "../../"

action_targets = var.action_targets
auto_enable_controls = var.auto_enable_controls
control_finding_generator = var.control_finding_generator
enable_default_standards = var.enable_default_standards
product_subscription_arns = var.product_subscription_arns
standard_subscription_arns = var.standard_subscription_arns
standards_controls = var.standards_controls
security_hub = var.security_hub
}

# Send invite from administrator account
module "member" {
source = "../member"

providers = {
aws = aws.administrator
}
resource "aws_securityhub_member" "this" {
provider = aws.administrator

account_id = module.account.account.id
email = var.member_email
email = var.security_hub.member_email
invite = true
}

# Accept invite
module "accept" {
source = "../accepter"

depends_on = [module.account]
resource "aws_securityhub_invite_accepter" "this" {
master_id = terraform_data.accepter_dependencies.input.master_id
}

master_account_id = module.member.member.master_id
# Creates dependency on `module.account.account.id`, so security hub is enabled
# in the account before the invite can be accepted
resource "terraform_data" "accepter_dependencies" {
input = {
master_id = coalesce(var.security_hub.master_id, aws_securityhub_member.this.master_id)
account_id = module.account.account.id
}
}
18 changes: 4 additions & 14 deletions modules/cross-account-member/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
output "account" {
description = "Object containing the SecurityHub account resource"
value = module.account.account
description = "Object containing the SecurityHub resources"
value = module.account
}

output "member" {
description = "Object containing the SecurityHub member resource"
value = module.member.member
value = aws_securityhub_member.this
}

output "accepter" {
description = "Object containing the SecurityHub accepter resource"
value = module.accept.accepter
}

output "subscriptions" {
description = "Object containing the SecurityHub subscriptions resources"
value = module.account.subscriptions
}

output "action_targets" {
description = "Object containing the SecurityHub action targets resources"
value = module.account.action_targets
value = aws_securityhub_invite_accepter.this
}
74 changes: 24 additions & 50 deletions modules/cross-account-member/variables.tf
Original file line number Diff line number Diff line change
@@ -1,55 +1,29 @@
variable "member_email" {
description = "Email address associated with the member account. Required for the cross-account SecurityHub member invite workflow"
type = string
}

variable "action_targets" {
description = "Schema list of SecurityHub action targets."
type = list(object({
name = string
description = string
identifer = string
}))
default = []
}

variable "auto_enable_controls" {
description = "Boolean that enables the security standards that Security Hub has designated as automatically enabled including: `AWS Foundational Security Best Practices v1.0.0` and `CIS AWS Foundations Benchmark v1.2.0`"
type = bool
default = true
}
variable "security_hub" {
description = "Object of inputs for Security Hub configuration"
nullable = false
type = object({
member_email = string
master_id = optional(string)

variable "control_finding_generator" {
description = "Manages whether the account reports consolidated control findings, or generates separate findings for every enabled standard."
type = string
default = "SECURITY_CONTROL"
}
auto_enable_controls = optional(bool, true)
control_finding_generator = optional(string)
enable_default_standards = optional(bool, true)

variable "enable_default_standards" {
description = "Boolean that automatically enables new controls when they are added to standards that are enabled"
type = bool
default = true
}
product_subscription_arns = optional(list(string), [])
standard_subscription_arns = optional(list(string), [])

variable "product_subscription_arns" {
description = "List of product arns to subscribe to. See https://www.terraform.io/docs/providers/aws/r/securityhub_product_subscription.html"
type = list(string)
default = []
}

variable "standard_subscription_arns" {
description = "List of standard arns to subscribe to. See https://www.terraform.io/docs/providers/aws/r/securityhub_standards_subscription.html"
type = list(string)
default = []
}
action_targets = optional(list(object({
name = string
description = string
identifier = string
})), [])

variable "standards_controls" {
description = "List of Security Hub standards to enable or disable in current region."
type = list(object({
name = string
standards_control_arn = string
control_status = string
disabled_reason = string
}))
default = []
standards_control_associations = optional(list(object({
name = string
association_status = string
security_control_id = string
standards_arn = string
updated_reason = optional(string)
})), [])
})
}
4 changes: 2 additions & 2 deletions modules/cross-account-member/versions.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 0.13"
required_version = ">= 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.64.0"
version = ">= 5.70.0"
configuration_aliases = [aws.administrator]
}
}
Expand Down
79 changes: 47 additions & 32 deletions tests/test-cross-account/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,45 +18,60 @@ module "securityhub_owner" {
}
}

module "securityhub" {
module "security_hub" {
source = "../../modules/cross-account-member"

providers = {
aws.administrator = aws.administrator
}

# Without the following line it takes two attepts to destroy the resources created by the test
depends_on = [module.securityhub_owner]

member_email = var.member_email

standard_subscription_arns = [
"arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.2.0",
"arn:aws:securityhub:us-east-1::standards/pci-dss/v/3.2.1",
]

product_subscription_arns = [
"arn:aws:securityhub:us-east-1:453761072151:product/turbot/turbot",
]

standards_controls = [
{
name = "cis-aws-foundations-benchmark"
standards_control_arn = "arn:aws:securityhub:us-east-1:303523384066:control/cis-aws-foundations-benchmark/v/1.2.0/1.10"
control_status = "ENABLED"
disabled_reason = ""
},
{
name = "pci-dss"
standards_control_arn = "arn:aws:securityhub:us-east-1:303523384066:control/pci-dss/v/3.2.1/PCI.AutoScaling.1"
control_status = "DISABLED"
disabled_reason = "I don't like security"
}
]
}
security_hub = {
member_email = var.member_email
master_id = module.securityhub_owner.account.id

auto_enable_controls = true
control_finding_generator = null # "SECURITY_CONTROL|STANDARD_CONTROL"
enable_default_standards = true # Enables CIS AWS Foundations and AWS Foundational Security Best Practices

standard_subscription_arns = [
"arn:${local.partition}:securityhub:${local.region}::standards/aws-resource-tagging-standard/v/1.0.0",
"arn:${local.partition}:securityhub:${local.region}::standards/pci-dss/v/3.2.1",
]

output "securityhub" {
value = module.securityhub
product_subscription_arns = [
"arn:${local.partition}:securityhub:${local.region}:453761072151:product/turbot/turbot",
]

standards_control_associations = [
{
name = "cis-foundations-cloudtrail-2"
association_status = "DISABLED"
security_control_id = "CloudTrail.2"
updated_reason = "I don't like security"
standards_arn = "arn:${local.partition}:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.2.0"
},
{
name = "aws-foundations-cloudtrail-2"
association_status = "DISABLED"
security_control_id = "CloudTrail.2"
updated_reason = "I don't like security"
standards_arn = "arn:${local.partition}:securityhub:${local.region}::standards/aws-foundational-security-best-practices/v/1.0.0"
},
{
name = "pci-dss-cloudtrail-2"
association_status = "DISABLED"
security_control_id = "CloudTrail.2"
updated_reason = "I don't like security"
standards_arn = "arn:${local.partition}:securityhub:${local.region}::standards/pci-dss/v/3.2.1"
},
]
}
}

locals {
partition = data.aws_partition.current.partition
region = data.aws_region.current.name
}

data "aws_partition" "current" {}
data "aws_region" "current" {}
4 changes: 2 additions & 2 deletions tests/test-same-account/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ module "security_hub" {
}

locals {
partition = data.aws_partition.current.partition
region = data.aws_region.current.name
partition = data.aws_partition.current.partition
region = data.aws_region.current.name
}

data "aws_partition" "current" {}
Expand Down
2 changes: 2 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
variable "security_hub" {
description = "Object of inputs for Security Hub configuration"
nullable = false
type = object({
auto_enable_controls = optional(bool, true)
control_finding_generator = optional(string)
Expand All @@ -22,6 +23,7 @@ variable "security_hub" {
updated_reason = optional(string)
})), [])
})
default = {}

validation {
condition = anytrue([
Expand Down

0 comments on commit 386a2bc

Please sign in to comment.