Skip to content

Commit

Permalink
feat(benchmarks) Support org with stacksets
Browse files Browse the repository at this point in the history
  • Loading branch information
nkraemer-sysdig committed Oct 18, 2021
1 parent 38a5c00 commit 7e7369b
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 73 deletions.
10 changes: 3 additions & 7 deletions examples-internal/single-account-benchmark/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@ provider "sysdig" {
sysdig_secure_insecure_tls = length(regexall("https://.*?\\.sysdig(cloud)?.com/?", var.sysdig_secure_endpoint)) == 1 ? false : true
}


data "aws_caller_identity" "me" {}

module "cloud_bench" {
source = "../../modules/services/cloud-bench"

account_id = data.aws_caller_identity.me.account_id
tags = var.tags
regions = var.benchmark_regions
name = "${var.name}-cloudbench"
name = "${var.name}-cloudbench"
tags = var.tags
benchmark_regions = var.benchmark_regions
}
2 changes: 1 addition & 1 deletion examples-internal/single-account-benchmark/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ terraform {
required_version = ">= 0.15.0"
required_providers {
aws = {
version = ">= 3.50.0"
version = ">= 3.62.0"
}
sysdig = {
source = "sysdiglabs/sysdig"
Expand Down
35 changes: 14 additions & 21 deletions examples/organizational/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -96,27 +96,6 @@ module "cloud_connector" {
depends_on = [module.cloudtrail, module.ecs_fargate_cluster, module.ssm]
}


#
# cloud-bench
# WIP
#

#data "aws_caller_identity" "me" {}
#module "cloud_bench" {
# providers = {
# aws = aws.member
# }
# source = "../../modules/services/cloud-bench"
#
# account_id = var.organizational_config.sysdig_secure_for_cloud_member_account_id
# tags = var.tags
#}





#
# cloud-scanning
#
Expand Down Expand Up @@ -161,3 +140,17 @@ module "cloud_scanning" {
tags = var.tags
depends_on = [module.cloudtrail, module.ecs_fargate_cluster, module.codebuild, module.ssm]
}

#-------------------------------------
# cloud-bench
#-------------------------------------

module "cloud_bench" {
source = "../../modules/services/cloud-bench"

name = "${var.name}-cloudbench"
tags = var.tags
is_organizational = true
region = var.region
benchmark_regions = var.benchmark_regions
}
11 changes: 10 additions & 1 deletion examples/organizational/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ variable "cloudtrail_kms_enable" {
description = "true/false whether cloudtrail delivered events to S3 should persist encrypted"
}

#
# benchmark configuration
#

variable "benchmark_regions" {
type = list(string)
description = "List of regions in which to run the benchmark. If empty, the task will contain all aws regions by default."
default = []
}

#
# general
#
Expand All @@ -51,7 +61,6 @@ variable "region" {
description = "Default region for resource creation in both organization master and secure-for-cloud member account"
}


variable "name" {
type = string
description = "Name to be assigned to all child resources. A suffix may be added internally when required. Use default value unless you need to install multiple instances"
Expand Down
2 changes: 1 addition & 1 deletion examples/organizational/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ terraform {
required_version = ">= 0.15.0"
required_providers {
aws = {
version = ">= 3.50.0"
version = ">= 3.62.0"
}
sysdig = {
source = "sysdiglabs/sysdig"
Expand Down
9 changes: 3 additions & 6 deletions examples/single-account/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ module "cloud_scanning" {
#-------------------------------------
# cloud-bench
#-------------------------------------
data "aws_caller_identity" "me" {}

provider "sysdig" {
sysdig_secure_url = var.sysdig_secure_endpoint
sysdig_secure_api_token = var.sysdig_secure_api_token
Expand All @@ -110,9 +108,8 @@ provider "sysdig" {

module "cloud_bench" {
source = "../../modules/services/cloud-bench"
name = "${var.name}-cloudbench"

account_id = data.aws_caller_identity.me.account_id
tags = var.tags
regions = var.benchmark_regions
name = "${var.name}-cloudbench"
tags = var.tags
benchmark_regions = var.benchmark_regions
}
15 changes: 9 additions & 6 deletions examples/single-account/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ variable "cloudtrail_kms_enable" {
description = "true/false whether cloudtrail delivered events to S3 should persist encrypted"
}

#
# benchmark configuration
#

variable "benchmark_regions" {
type = list(string)
description = "List of regions in which to run the benchmark. If empty, the task will contain all aws regions by default."
default = []
}

#
# general
Expand Down Expand Up @@ -54,9 +63,3 @@ variable "tags" {
"product" = "sysdig-secure-for-cloud"
}
}

variable "benchmark_regions" {
type = list(string)
description = "List of regions in which to run the benchmark. If empty, the task will contain all aws regions by default."
default = []
}
2 changes: 1 addition & 1 deletion examples/single-account/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ terraform {
required_version = ">= 0.15.0"
required_providers {
aws = {
version = ">= 3.50.0"
version = ">= 3.62.0"
}
sysdig = {
source = "sysdiglabs/sysdig"
Expand Down
120 changes: 98 additions & 22 deletions modules/services/cloud-bench/main.tf
Original file line number Diff line number Diff line change
@@ -1,26 +1,48 @@
#
# Sysdig Secure cloud provisioning
#
resource "sysdig_secure_cloud_account" "cloud_account" {
account_id = var.account_id
#----------------------------------------------------------
# Fetch & compute required data
#----------------------------------------------------------

data "aws_caller_identity" "me" {}

data "aws_organizations_organization" "org" {}

data "sysdig_secure_trusted_cloud_identity" "trusted_identity" {
cloud_provider = "aws"
role_enabled = "true"
role_name = var.name
}

data "sysdig_secure_trusted_cloud_identity" "trusted_identity" {
locals {
member_account_ids = var.is_organizational ? [for a in data.aws_organizations_organization.org.non_master_accounts : a.id] : []

benchmark_task_name = var.is_organizational ? "Organization: ${data.aws_organizations_organization.org.id}" : data.aws_caller_identity.me.account_id
accounts_scope_clause = var.is_organizational ? "aws.accountId in (\"${join("\", \"", local.member_account_ids)}\")" : "aws.accountId = \"${data.aws_caller_identity.me.account_id}\""
regions_scope_clause = length(var.benchmark_regions) == 0 ? "" : " and aws.region in (\"${join("\", \"", var.benchmark_regions)}\")"
}

#----------------------------------------------------------
# Configure Sysdig Backend
#----------------------------------------------------------

resource "sysdig_secure_cloud_account" "cloud_account" {
for_each = var.is_organizational ? toset(local.member_account_ids) : [data.aws_caller_identity.me.account_id]

account_id = each.value
cloud_provider = "aws"
role_enabled = "true"
role_name = var.name
}

locals {
regions_scope_clause = length(var.regions) == 0 ? "" : " and aws.region in (\"${join("\", \"", var.regions)}\")"
external_id = try(
sysdig_secure_cloud_account.cloud_account[local.member_account_ids[0]].external_id,
sysdig_secure_cloud_account.cloud_account[data.aws_caller_identity.me.account_id].external_id,
)
}

resource "sysdig_secure_benchmark_task" "benchmark_task" {
name = "Sysdig Secure for Cloud (AWS) - ${var.account_id}"
name = "Sysdig Secure for Cloud (AWS) - ${local.benchmark_task_name}"
schedule = "0 6 * * *"
schema = "aws_foundations_bench-1.3.0"
scope = "aws.accountId = \"${var.account_id}\"${local.regions_scope_clause}"
scope = "${local.accounts_scope_clause}${local.regions_scope_clause}"

# Creation of a task requires that the Cloud Account already exists in the backend, and has `role_enabled = true`
# We only want to create the task once the rust relationship is established, otherwise running the task will fail.
Expand All @@ -30,14 +52,13 @@ resource "sysdig_secure_benchmark_task" "benchmark_task" {
]
}

#
# aws role provisioning
#

resource "aws_iam_role" "cloudbench_role" {
name = var.name
assume_role_policy = data.aws_iam_policy_document.trust_relationship.json
tags = var.tags
#----------------------------------------------------------
# If this is not an Organizational deploy, create role/polices directly
#----------------------------------------------------------

data "aws_iam_policy" "security_audit" {
arn = "arn:aws:iam::aws:policy/SecurityAudit"
}

data "aws_iam_policy_document" "trust_relationship" {
Expand All @@ -51,16 +72,71 @@ data "aws_iam_policy_document" "trust_relationship" {
condition {
test = "StringEquals"
variable = "sts:ExternalId"
values = [sysdig_secure_cloud_account.cloud_account.external_id]
values = [local.external_id]
}
}
}

resource "aws_iam_role" "cloudbench_role" {
count = var.is_organizational ? 0 : 1

name = var.name
assume_role_policy = data.aws_iam_policy_document.trust_relationship.json
tags = var.tags
}


resource "aws_iam_role_policy_attachment" "cloudbench_security_audit" {
role = aws_iam_role.cloudbench_role.id
count = var.is_organizational ? 0 : 1

role = aws_iam_role.cloudbench_role[0].id
policy_arn = data.aws_iam_policy.security_audit.arn
}

data "aws_iam_policy" "security_audit" {
arn = "arn:aws:iam::aws:policy/SecurityAudit"

#----------------------------------------------------------
# If this is an Organizational deploy, use a CloudFormation StackSet
#----------------------------------------------------------

resource "aws_cloudformation_stack_set" "stackset" {
count = var.is_organizational ? 1 : 0

name = var.name
tags = var.tags
permission_model = "SERVICE_MANAGED"
capabilities = ["CAPABILITY_NAMED_IAM"]

auto_deployment {
enabled = true
retain_stacks_on_account_removal = false
}

template_body = <<TEMPLATE
Resources:
SysdigCloudBench:
Type: AWS::IAM::Role
Properties:
RoleName: ${var.name}
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
AWS: [ ${data.sysdig_secure_trusted_cloud_identity.trusted_identity.identity} ]
Action: [ 'sts:AssumeRole' ]
Condition:
StringEquals:
sts:ExternalId: ${local.external_id}
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/SecurityAudit"
TEMPLATE
}

resource "aws_cloudformation_stack_set_instance" "stackset_instance" {
count = var.is_organizational ? 1 : 0

region = var.region
stack_set_name = aws_cloudformation_stack_set.stackset[0].name
deployment_targets {
organizational_unit_ids = [for root in data.aws_organizations_organization.org.roots : root.id]
}
}
19 changes: 13 additions & 6 deletions modules/services/cloud-bench/variables.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
variable "account_id" {
type = string
description = "the account_id in which to provision the cloud-bench IAM role"
}

#---------------------------------
# optionals - with default
#---------------------------------
Expand All @@ -13,7 +8,19 @@ variable "name" {
default = "sfc-cloudbench"
}

variable "regions" {
variable "is_organizational" {
type = bool
default = false
description = "whether secure-for-cloud should be deployed in an organizational setup"
}

variable "region" {
type = string
default = "eu-central-1"
description = "Default region for resource creation in organization mode"
}

variable "benchmark_regions" {
type = list(string)
description = "List of regions in which to run the benchmark. If empty, the task will contain all aws regions by default."
default = []
Expand Down
2 changes: 1 addition & 1 deletion modules/services/cloud-bench/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ terraform {
required_version = ">= 0.15.0"
required_providers {
aws = {
version = ">= 3.50.0"
version = ">= 3.62.0"
}
sysdig = {
source = "sysdiglabs/sysdig"
Expand Down

0 comments on commit 7e7369b

Please sign in to comment.