Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8ae19d0
Preliminary work for management account.
fcracker79 Nov 25, 2025
ac094fc
Attempt to use stackset to deploy lambdas to all specified regions.
fcracker79 Nov 25, 2025
0f93d87
Roles extracted from cloudformation stack as they are not regional.
fcracker79 Nov 25, 2025
2f23ad9
Some fixes
fcracker79 Nov 26, 2025
4a11f2c
Adopting the strategy of fetching lambdas from Sysdig public S3 buckets.
fcracker79 Nov 26, 2025
a4377d2
WORKING
fcracker79 Nov 27, 2025
34e9550
Added the possibility to disable some actions.
fcracker79 Nov 27, 2025
831a65f
Preliminary support for subaccounts
fcracker79 Nov 27, 2025
01d8ad9
Fixed organizational stuff
fcracker79 Nov 28, 2025
708f9ea
Other fixes.
fcracker79 Nov 28, 2025
05fb112
Some comments
fcracker79 Nov 28, 2025
d5effcc
Short names in tags
fcracker79 Nov 28, 2025
a2fa084
Simple names as tags in resources
fcracker79 Nov 28, 2025
c6cc633
Removing unnecessary stuff
fcracker79 Nov 28, 2025
b00b92f
Initial change to support sysdig components
fcracker79 Nov 28, 2025
a15cf12
Other fixes.
fcracker79 Dec 1, 2025
32e011d
Fixed version.
fcracker79 Dec 2, 2025
b0c7db0
Added components outputs
fcracker79 Dec 4, 2025
f344382
Creating S3 storage and lambda to upload lambda code
fcracker79 Dec 9, 2025
b475686
Fix indent
fcracker79 Dec 10, 2025
178f0ce
Fixed.
fcracker79 Dec 10, 2025
d6971c0
Merge branch 'main' into feat/mirko/ra-stackset
fcracker79 Dec 10, 2025
479952b
Set new terraform plugin
fcracker79 Dec 12, 2025
c26ad28
Fixed readme
fcracker79 Dec 12, 2025
3724189
Some cleanup
fcracker79 Dec 12, 2025
ee78421
Removed versioning and normalizing bucket names
fcracker79 Dec 12, 2025
70436ba
Aligning terraform plugin
fcracker79 Dec 12, 2025
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
2 changes: 1 addition & 1 deletion modules/config-posture/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ terraform {
}
sysdig = {
source = "sysdiglabs/sysdig"
version = "~> 1.48"
version = "~> 3.3"
}
}
}
2 changes: 1 addition & 1 deletion modules/integrations/cloud-logs/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ terraform {
}
sysdig = {
source = "sysdiglabs/sysdig"
version = "~> 1.56"
version = "~> 3.3"
}
random = {
source = "hashicorp/random"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ terraform {
}
sysdig = {
source = "sysdiglabs/sysdig"
version = "~> 1.48"
version = "~> 3.3"
}
random = {
source = "hashicorp/random"
Expand Down
2 changes: 1 addition & 1 deletion modules/integrations/event-bridge/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ terraform {
}
sysdig = {
source = "sysdiglabs/sysdig"
version = "~> 1.51"
version = "~> 3.3"
}
random = {
source = "hashicorp/random"
Expand Down
2 changes: 1 addition & 1 deletion modules/onboarding/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ terraform {
}
sysdig = {
source = "sysdiglabs/sysdig"
version = "~> 1.48"
version = "~> 3.3"
}
}
}
12 changes: 12 additions & 0 deletions modules/response-actions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
For testing, create `provisioning.tf`, with:

```
provider "sysdig" {
sysdig_secure_url = "<Sysdig endpoint>"
sysdig_secure_api_token = "<Sysdig API key>"
}

provider "aws" {
region = "us-east-1"
}
```
182 changes: 182 additions & 0 deletions modules/response-actions/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#-----------------------------------------------------------------------------------------------------------------------------------------
# Organizational Deployment Configuration
#
# This file contains the logic for determining which organizational units (OUs) and accounts to deploy Response Actions to
# in an AWS Organization deployment.
#
# The module supports flexible inclusion/exclusion patterns:
# - include_ouids/exclude_ouids: Include or exclude entire organizational units
# - include_accounts/exclude_accounts: Include or exclude specific accounts
#
# Key behavior:
# 1. Inclusions are always prioritized over exclusions
# 2. The management account is automatically excluded from delegate role deployment (roles exist there already)
# 3. Due to AWS CloudFormation limitations with UNION filters, when including specific accounts, the stackset
# deploys to the entire org (with account filtering handled by Sysdig backend)
#
#-----------------------------------------------------------------------------------------------------------------------------------------

#----------------------------------------------------------
# Fetch & compute required data for organizational install
#----------------------------------------------------------

data "aws_organizations_organization" "org" {
count = var.is_organizational ? 1 : 0
}

locals {
# fetch the AWS Root OU under org
# As per https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html#organization-structure, there can be only one root
root_org_unit = var.is_organizational ? [for root in data.aws_organizations_organization.org[0].roots : root.id] : []
}

# *****************************************************************************************************************************************************
# INCLUDE/EXCLUDE CONFIGURATION SUPPORT
#
# 1. Inclusions will always be handled for TF cloud provisioning.
# NOTE:
# Till AWS issue with UNION filter (https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-cloudformation/issues/100)
# is fixed, we can't deploy using UNION filters for inclusions. As a workaround to ensure we don't skip any accounts, we deploy it to entire org.
#
# 2. We handle exclusions when only exclusion parameters are provided i.e out of all 4 configuration inputs,
# a. only exclude_ouids are provided, OR
# b. only exclude_accounts are provided, OR
# c. only exclude_ouids AND exclude_accounts are provided
# Else we ignore exclusions during cloud resource provisioning through TF. This is because AWS does not allow both operations - to include some
# accounts and to exclude some. Hence, we will always prioritize include over exclude.
#
# 3. Sysdig however will honor all combinations of configuration inputs exactly as desired.
# *****************************************************************************************************************************************************

#------------------------------------------------------------
# Manage configurations to determine OU targets to deploy in
#------------------------------------------------------------

locals {
# OU CONFIGURATION (determine user provided org configuration)
org_configuration = (
# case1 - if no include/exclude ous provided, include entire org
var.is_organizational && length(var.include_ouids) == 0 && length(var.exclude_ouids) == 0 ? (
"entire_org"
) : (
# case2 - if only included ouids provided, include those ous only
var.is_organizational && length(var.include_ouids) > 0 && length(var.exclude_ouids) == 0 ? (
"included_ous_only"
) : (
# case3 - if only excluded ouids provided, exclude their accounts from rest of org
var.is_organizational && length(var.include_ouids) == 0 && length(var.exclude_ouids) > 0 ? (
"excluded_ous_only"
) : (
# case4 - if both include and exclude ouids are provided, includes override excludes
var.is_organizational && length(var.include_ouids) > 0 && length(var.exclude_ouids) > 0 ? (
"mixed_ous"
) : ""
)
)
)
)

# switch cases for various user provided org configuration to be onboarded
deployment_options = {
entire_org = {
org_units_to_deploy = local.root_org_unit
}
included_ous_only = {
org_units_to_deploy = var.include_ouids
}
excluded_ous_only = {
# onboard entire org and filter out all accounts in excluded OUs using account filter
org_units_to_deploy = local.root_org_unit
}
mixed_ous = {
# if both include and exclude ouids are provided, includes override excludes
org_units_to_deploy = var.include_ouids
}
default = {
org_units_to_deploy = local.root_org_unit
}
}

# final targets to deploy organizational resources in
deployment_targets_ous = lookup(local.deployment_options, local.org_configuration, local.deployment_options.default)

exclude_root_ou = length(local.root_org_unit) > 0 ? contains(var.exclude_ouids, local.root_org_unit[0]) : false
}

#-----------------------------------------------------------------
# Manage configurations to determine account targets to deploy in
#-----------------------------------------------------------------

# if only exclude_ouids are provided and as long as it isn't Root OU, fetch all their child accounts to filter exclusions
data "aws_organizations_organizational_unit_descendant_accounts" "ou_accounts_to_exclude" {
for_each = local.org_configuration == "excluded_ous_only" && !local.exclude_root_ou ? var.exclude_ouids : []
parent_id = each.key
}

locals {
# ACCOUNTS CONFIGURATION (determine user provided accounts configuration)
accounts_configuration = (
# case1 - if only included accounts provided, include those accts as well
var.is_organizational && length(var.include_accounts) > 0 && length(var.exclude_accounts) == 0 ? (
"UNION"
) : (
# case2 - if only excluded accounts or only excluded ouids provided, exclude those accounts
var.is_organizational && length(var.include_accounts) == 0 && (length(var.exclude_accounts) > 0 || local.org_configuration == "excluded_ous_only") ? (
"DIFFERENCE"
) : (
# case3 - if both include and exclude accounts are provided, includes override excludes
var.is_organizational && length(var.include_accounts) > 0 && length(var.exclude_accounts) > 0 ? (
"MIXED"
# case4 - if no explicit include/exclude, we still need to exclude current account
) : var.is_organizational ? (
"DIFFERENCE"
) : ""
)
)
)

ou_accounts_to_exclude = flatten([for ou_accounts in data.aws_organizations_organizational_unit_descendant_accounts.ou_accounts_to_exclude : [ou_accounts.accounts[*].id]])
# Always exclude the current account (management account) from StackSet deployment since the Lambda execution roles
# already exist in the management account. Delegate roles are only needed in member accounts.
accounts_to_exclude = setunion(local.ou_accounts_to_exclude, var.exclude_accounts, [data.aws_caller_identity.current.account_id])

# switch cases for various user provided accounts configuration to be onboarded
deployment_account_options = {
NONE = {
accounts_to_deploy = []
account_filter_type = "NONE"
}
UNION = {
accounts_to_deploy = var.include_accounts
account_filter_type = "UNION"
}
DIFFERENCE = {
accounts_to_deploy = local.accounts_to_exclude
account_filter_type = "DIFFERENCE"
}
MIXED = {
accounts_to_deploy = var.include_accounts
account_filter_type = "UNION"
}
default = {
# default when neither of include/exclude accounts are provided
accounts_to_deploy = []
account_filter_type = "NONE"
}
}

# list of accounts to deploy organizational resources in
deployment_targets_accounts = lookup(local.deployment_account_options, local.accounts_configuration, local.deployment_account_options.default)
}

# -----------------------------------------------------------------------------------------------------
# Remove below conditional once AWS issue is fixed -
# https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-cloudformation/issues/100
# -----------------------------------------------------------------------------------------------------
locals {
# XXX: due to AWS bug of not having UNION filter fully working, there is no way to add those extra accounts requested.
# to not miss out on those extra accounts, deploy the cloud resources across entire org and noop the UNION filter.
# i.e till we can't deploy UNION, we deploy it all
deployment_targets_org_units = local.deployment_targets_accounts.account_filter_type == "UNION" ? local.root_org_unit : local.deployment_targets_ous.org_units_to_deploy
deployment_targets_accounts_filter = local.deployment_targets_accounts.account_filter_type == "UNION" ? "NONE" : local.deployment_targets_accounts.account_filter_type
}
Loading