Skip to content

Commit

Permalink
delegated admin account (#78)
Browse files Browse the repository at this point in the history
* delegated admin account

* renamed variable

* cleaned up stackset deployment logic

* minor readme correction

* formatting fixes
  • Loading branch information
jameslarrea authored Jul 31, 2024
1 parent 662ad72 commit f3be96e
Show file tree
Hide file tree
Showing 13 changed files with 78 additions and 14 deletions.
1 change: 1 addition & 0 deletions modules/services/agentless-scanning/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ No modules.
| <a name="input_stackset_admin_role_arn"></a> [stackset\_admin\_role\_arn](#input\_stackset\_admin\_role\_arn) | (Optional) stackset admin role to run SELF\_MANAGED stackset | `string` | `""` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | sysdig secure-for-cloud tags. always include 'product' default tag for resource-group proper functioning | `map(string)` | <pre>{<br> "product": "sysdig-secure-for-cloud"<br>}</pre> | no |
| <a name="input_timeout"></a> [timeout](#input\_timeout) | Default timeout values for create, update, and delete operations | `string` | `"30m"` | no |
| <a name="delegated_admin"></a> [delegated_admin](#input\_delegated\_admin) | Whether to create the resources using an delegated admin account | `bool` | `false` | no |

## Outputs

Expand Down
9 changes: 9 additions & 0 deletions modules/services/agentless-scanning/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,12 @@ locals {
account_id = data.aws_caller_identity.current.account_id
caller_arn = data.aws_iam_session_context.current.issuer_arn
}

#-----------------------------------------------------------------------------------------------------------------------
# Dertermine whether to deploy self-managed stacksets in the management account.
# This might be disabled if using a delegated admin account or to avoid creating a stackset admin and execution role
# in the management account.
#-----------------------------------------------------------------------------------------------------------------------
locals {
deploy_stackset = var.mgt_stackset && !var.delegated_admin
}
10 changes: 5 additions & 5 deletions modules/services/agentless-scanning/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#-----------------------------------------------------------------------------------------------------------------------

data "aws_iam_policy_document" "scanning" {
count = (var.deploy_global_resources || var.is_organizational && var.mgt_stackset) ? 1 : 0
count = (var.deploy_global_resources || (var.is_organizational && local.deploy_stackset)) ? 1 : 0

# General read permission, necessary for the discovery phase.
statement {
Expand Down Expand Up @@ -184,7 +184,7 @@ data "aws_iam_policy_document" "scanning" {
}

resource "aws_iam_policy" "scanning" {
count = (var.deploy_global_resources || var.is_organizational && var.mgt_stackset) ? 1 : 0
count = (var.deploy_global_resources || (var.is_organizational && local.deploy_stackset)) ? 1 : 0

name = var.name
description = "Grants Sysdig Secure access to volumes and snapshots"
Expand All @@ -193,7 +193,7 @@ resource "aws_iam_policy" "scanning" {
}

data "aws_iam_policy_document" "scanning_assume_role_policy" {
count = (var.deploy_global_resources || var.is_organizational && var.mgt_stackset) ? 1 : 0
count = (var.deploy_global_resources || (var.is_organizational && local.deploy_stackset)) ? 1 : 0

statement {
sid = "SysdigSecureScanning"
Expand All @@ -218,15 +218,15 @@ data "aws_iam_policy_document" "scanning_assume_role_policy" {
}

resource "aws_iam_role" "scanning" {
count = (var.deploy_global_resources || var.is_organizational && var.mgt_stackset) ? 1 : 0
count = (var.deploy_global_resources || (var.is_organizational && local.deploy_stackset)) ? 1 : 0

name = var.name
tags = var.tags
assume_role_policy = data.aws_iam_policy_document.scanning_assume_role_policy[0].json
}

resource "aws_iam_policy_attachment" "scanning" {
count = (var.deploy_global_resources || var.is_organizational && var.mgt_stackset) ? 1 : 0
count = (var.deploy_global_resources || (var.is_organizational && local.deploy_stackset)) ? 1 : 0

name = var.name
roles = [aws_iam_role.scanning[0].name]
Expand Down
12 changes: 10 additions & 2 deletions modules/services/agentless-scanning/organizational.tf
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ resource "aws_cloudformation_stack_set" "scanning_role_stackset" {
ignore_changes = [administration_role_arn]
}

call_as = var.delegated_admin ? "DELEGATED_ADMIN" : "SELF"

template_body = <<TEMPLATE
Resources:
AgentlessScanningRole:
Expand Down Expand Up @@ -144,6 +146,8 @@ resource "aws_cloudformation_stack_set_instance" "scanning_role_stackset_instanc
# Roles are not regional and hence do not need regional parallelism
}

call_as = var.delegated_admin ? "DELEGATED_ADMIN" : "SELF"

timeouts {
create = var.timeout
update = var.timeout
Expand All @@ -159,7 +163,7 @@ resource "aws_cloudformation_stack_set_instance" "scanning_role_stackset_instanc

# stackset to deploy resources for agentless scanning in management account
resource "aws_cloudformation_stack_set" "mgmt_acc_resources_stackset" {
count = var.is_organizational && var.mgt_stackset ? 1 : 0
count = var.is_organizational && local.deploy_stackset ? 1 : 0
depends_on = [aws_iam_role.scanning]

name = join("-", [var.name, "ScanningKmsMgmtAcc"])
Expand Down Expand Up @@ -217,7 +221,7 @@ TEMPLATE

# stackset instance to deploy resources for agentless scanning, in all regions of the management account
resource "aws_cloudformation_stack_set_instance" "mgmt_acc_stackset_instance" {
for_each = var.mgt_stackset ? local.region_set : toset([])
for_each = local.deploy_stackset ? local.region_set : toset([])
region = each.key

stack_set_name = aws_cloudformation_stack_set.mgmt_acc_resources_stackset[0].name
Expand Down Expand Up @@ -263,6 +267,8 @@ resource "aws_cloudformation_stack_set" "ou_resources_stackset" {
ignore_changes = [administration_role_arn]
}

call_as = var.delegated_admin ? "DELEGATED_ADMIN" : "SELF"

template_body = <<TEMPLATE
Resources:
AgentlessScanningKmsPrimaryKey:
Expand Down Expand Up @@ -320,6 +326,8 @@ resource "aws_cloudformation_stack_set_instance" "ou_stackset_instance" {
region_concurrency_type = "PARALLEL"
}

call_as = var.delegated_admin ? "DELEGATED_ADMIN" : "SELF"

timeouts {
create = var.timeout
update = var.timeout
Expand Down
7 changes: 7 additions & 0 deletions modules/services/agentless-scanning/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,10 @@ variable "failure_tolerance_percentage" {
description = "The percentage of accounts, per Region, for which stack operations can fail before AWS CloudFormation stops the operation in that Region"
default = 90
}


variable "delegated_admin" {
description = "Whether a delegated admin account will be used"
type = bool
default = false
}
1 change: 1 addition & 0 deletions modules/services/event-bridge/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ No modules.
| <a name="input_stackset_admin_role_arn"></a> [stackset\_admin\_role\_arn](#input\_stackset\_admin\_role\_arn) | (Optional) stackset admin role to run SELF\_MANAGED stackset | `string` | `""` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | (Optional) Tags to be attached to all Sysdig resources. | `map(string)` | <pre>{<br> "product": "sysdig"<br>}</pre> | no |
| <a name="input_timeout"></a> [timeout](#input\_timeout) | Default timeout values for create, update, and delete operations | `string` | `"30m"` | no |
| <a name="delegated_admin"></a> [delegated_admin](#input\_delegated\_admin) | Whether to create the resources using an delegated admin account | `bool` | `false` | no |

## Outputs

Expand Down
17 changes: 13 additions & 4 deletions modules/services/event-bridge/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@
locals {
is_role_empty = length(var.role_arn) == 0
}

#-----------------------------------------------------------------------------------------------------------------------
# Dertermine whether to deploy self-managed stacksets in the management account.
# This might be disabled if using a delegated admin account or to avoid creating a stackset admin and execution role
# in the management account.
#-----------------------------------------------------------------------------------------------------------------------
locals {
deploy_stackset = var.mgt_stackset && !var.delegated_admin
}

#-----------------------------------------------------------------------------------------------------------------------
# Determine if this is an Organizational install, or a single account install. For Single Account installs, resources
# are created directly using the AWS Terraform Provider (This is the default behaviour). For Organizational installs,
Expand Down Expand Up @@ -56,10 +66,9 @@ resource "aws_cloudwatch_event_target" "sysdig" {
# Role that will be used by EventBridge when sending events to Sysdig's EventBridge Bus. The EventBridge service is
# given permission to assume this role.
resource "aws_iam_role" "event_bus_invoke_remote_event_bus" {
count = (var.is_organizational && var.mgt_stackset || var.deploy_global_resources) ? 1 : 0

name = var.name
tags = var.tags
count = ((var.is_organizational && local.deploy_stackset) || var.deploy_global_resources) ? 1 : 0
name = var.name
tags = var.tags

assume_role_policy = <<EOF
{
Expand Down
12 changes: 10 additions & 2 deletions modules/services/event-bridge/organizational.tf
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ resource "aws_cloudformation_stack_set" "eb-rule-stackset" {
ignore_changes = [administration_role_arn]
}

call_as = var.delegated_admin ? "DELEGATED_ADMIN" : "SELF"

template_body = templatefile("${path.module}/stackset_template_body.tpl", {
name = var.name
event_pattern = var.event_pattern
Expand All @@ -45,7 +47,7 @@ resource "aws_cloudformation_stack_set" "eb-rule-stackset" {

# stackset to deploy eventbridge rule in management account
resource "aws_cloudformation_stack_set" "mgmt-stackset" {
count = var.is_organizational && var.mgt_stackset ? 1 : 0
count = var.is_organizational && local.deploy_stackset ? 1 : 0

name = join("-", [var.name, "EBRuleMgmtAcc"])
tags = var.tags
Expand Down Expand Up @@ -91,6 +93,8 @@ resource "aws_cloudformation_stack_set" "eb-role-stackset" {
ignore_changes = [administration_role_arn]
}

call_as = var.delegated_admin ? "DELEGATED_ADMIN" : "SELF"

template_body = <<TEMPLATE
Resources:
EventBridgeRole:
Expand Down Expand Up @@ -143,6 +147,8 @@ resource "aws_cloudformation_stack_set_instance" "stackset_instance" {
region_concurrency_type = "PARALLEL"
}

call_as = var.delegated_admin ? "DELEGATED_ADMIN" : "SELF"

timeouts {
create = var.timeout
update = var.timeout
Expand All @@ -152,7 +158,7 @@ resource "aws_cloudformation_stack_set_instance" "stackset_instance" {

// stackset instance to deploy rule in all regions of management account
resource "aws_cloudformation_stack_set_instance" "mgmt_acc_stackset_instance" {
for_each = var.mgt_stackset ? local.region_set : toset([])
for_each = local.deploy_stackset ? local.region_set : toset([])
region = each.key
stack_set_name = aws_cloudformation_stack_set.mgmt-stackset[0].name

Expand Down Expand Up @@ -185,6 +191,8 @@ resource "aws_cloudformation_stack_set_instance" "eb_role_stackset_instance" {
# Roles are not regional and hence do not need regional parallelism
}

call_as = var.delegated_admin ? "DELEGATED_ADMIN" : "SELF"

timeouts {
create = var.timeout
update = var.timeout
Expand Down
3 changes: 2 additions & 1 deletion modules/services/event-bridge/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
output "role_arn" {
value = local.is_role_empty && var.mgt_stackset ? aws_iam_role.event_bus_invoke_remote_event_bus[0].arn : ""
value = local.is_role_empty && local.deploy_stackset ? aws_iam_role.event_bus_invoke_remote_event_bus[0].arn : ""

description = "ARN of cspm role"
}
7 changes: 7 additions & 0 deletions modules/services/event-bridge/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,10 @@ variable "failure_tolerance_percentage" {
description = "The percentage of accounts, per Region, for which stack operations can fail before AWS CloudFormation stops the operation in that Region"
default = 90
}


variable "delegated_admin" {
description = "Whether a delegated admin account will be used"
type = bool
default = false
}
1 change: 1 addition & 0 deletions modules/services/trust-relationship/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ No modules.
| <a name="input_role_name"></a> [role\_name](#input\_role\_name) | The name of the IAM Role that will be created. | `string` | `"sysdig-secure"` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | sysdig secure-for-cloud tags. always include 'product' default tag for resource-group proper functioning | `map(string)` | <pre>{<br> "product": "sysdig-secure-for-cloud"<br>}</pre> | no |
| <a name="input_timeout"></a> [timeout](#input\_timeout) | Default timeout values for create, update, and delete operations | `string` | `"30m"` | no |
| <a name="delegated_admin"></a> [delegated_admin](#input\_delegated\_admin) | Whether to create the resources using an delegated admin account | `bool` | `false` | no |

## Outputs

Expand Down
5 changes: 5 additions & 0 deletions modules/services/trust-relationship/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ locals {
# If this is not an Organizational deploy, create role/polices directly
#----------------------------------------------------------
resource "aws_iam_role" "cspm_role" {
count = var.delegated_admin ? 0 : 1
name = var.role_name
tags = var.tags
assume_role_policy = <<EOF
Expand Down Expand Up @@ -145,6 +146,8 @@ resource "aws_cloudformation_stack_set" "stackset" {
ignore_changes = [administration_role_arn]
}

call_as = var.delegated_admin ? "DELEGATED_ADMIN" : "SELF"

template_body = <<TEMPLATE
Resources:
SysdigCSPMRole:
Expand Down Expand Up @@ -212,6 +215,8 @@ resource "aws_cloudformation_stack_set_instance" "stackset_instance" {
# Roles are not regional and hence do not need regional parallelism
}

call_as = var.delegated_admin ? "DELEGATED_ADMIN" : "SELF"

timeouts {
create = var.timeout
update = var.timeout
Expand Down
7 changes: 7 additions & 0 deletions modules/services/trust-relationship/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,10 @@ variable "failure_tolerance_percentage" {
description = "The percentage of accounts, per Region, for which stack operations can fail before AWS CloudFormation stops the operation in that Region"
default = 90
}


variable "delegated_admin" {
description = "Whether a delegated admin account will be used"
type = bool
default = false
}

0 comments on commit f3be96e

Please sign in to comment.