diff --git a/examples/organizational/README.md b/examples/organizational/README.md index 206d3871..62690ba7 100644 --- a/examples/organizational/README.md +++ b/examples/organizational/README.md @@ -90,7 +90,6 @@ Notice that: |------|--------|---------| | [cloud\_bench](#module\_cloud\_bench) | ../../modules/services/cloud-bench | | | [cloud\_connector](#module\_cloud\_connector) | ../../modules/services/cloud-connector | | -| [cloud\_scanning](#module\_cloud\_scanning) | ../../modules/services/cloud-scanning | | | [cloudtrail](#module\_cloudtrail) | ../../modules/infrastructure/cloudtrail | | | [codebuild](#module\_codebuild) | ../../modules/infrastructure/codebuild | | | [ecs\_fargate\_cluster](#module\_ecs\_fargate\_cluster) | ../../modules/infrastructure/ecs-fargate-cluster | | @@ -119,6 +118,7 @@ Notice that: | [cloudtrail\_s3\_arn](#input\_cloudtrail\_s3\_arn) | ARN of a pre-existing cloudtrail\_sns s3 bucket. If it does not exist, it will be inferred from create cloudtrail | `string` | `"create"` | no | | [cloudtrail\_sns\_arn](#input\_cloudtrail\_sns\_arn) | ARN of a pre-existing cloudtrail\_sns. If it does not exist, it will be inferred from created cloudtrail | `string` | `"create"` | no | | [connector\_ecs\_task\_role\_name](#input\_connector\_ecs\_task\_role\_name) | Name for the ecs task role. This is only required to resolve cyclic dependency with organizational approach | `string` | `"organizational-ECSTaskRole"` | no | +| [deploy\_bench](#input\_deploy\_bench) | Whether to deploy or not the cloud benchmarking | `bool` | `true` | no | | [name](#input\_name) | 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 | `string` | `"sfc"` | no | | [organizational\_member\_default\_admin\_role](#input\_organizational\_member\_default\_admin\_role) | Default role created by AWS for managed-account users to be able to admin member accounts.
https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_accounts_access.html | `string` | `"OrganizationAccountAccessRole"` | no | | [region](#input\_region) | Default region for resource creation in both organization master and secure-for-cloud member account | `string` | `"eu-central-1"` | no | diff --git a/examples/organizational/main.tf b/examples/organizational/main.tf index 4aacfe7b..655c3317 100644 --- a/examples/organizational/main.tf +++ b/examples/organizational/main.tf @@ -53,36 +53,6 @@ module "ssm" { # # cloud-connector # -module "cloud_connector" { - providers = { - aws = aws.member - } - source = "../../modules/services/cloud-connector" - name = "${var.name}-cloudconnector" - - sysdig_secure_endpoint = var.sysdig_secure_endpoint - secure_api_token_secret_name = module.ssm.secure_api_token_secret_name - - is_organizational = true - organizational_config = { - sysdig_secure_for_cloud_role_arn = module.secure_for_cloud_role.sysdig_secure_for_cloud_role_arn - connector_ecs_task_role_name = aws_iam_role.connector_ecs_task.name - } - - sns_topic_arn = local.cloudtrail_sns_arn - - ecs_cluster = module.ecs_fargate_cluster.id - vpc_id = module.ecs_fargate_cluster.vpc_id - vpc_subnets = module.ecs_fargate_cluster.vpc_subnets - - tags = var.tags - depends_on = [local.cloudtrail_sns_arn, module.ecs_fargate_cluster, module.ssm] -} - -# -# cloud-scanning -# -## FIXME? if this is a non-shared resource, move its usage to scanning service? module "codebuild" { providers = { aws = aws.member @@ -93,13 +63,12 @@ module "codebuild" { depends_on = [module.ssm] } -module "cloud_scanning" { +module "cloud_connector" { providers = { aws = aws.member } - - source = "../../modules/services/cloud-scanning" - name = "${var.name}-cloudscanning" + source = "../../modules/services/cloud-connector" + name = "${var.name}-cloudconnector" sysdig_secure_endpoint = var.sysdig_secure_endpoint secure_api_token_secret_name = module.ssm.secure_api_token_secret_name @@ -111,7 +80,7 @@ module "cloud_scanning" { organizational_config = { sysdig_secure_for_cloud_role_arn = module.secure_for_cloud_role.sysdig_secure_for_cloud_role_arn organizational_role_per_account = var.organizational_member_default_admin_role - scanning_ecs_task_role_name = aws_iam_role.connector_ecs_task.name + connector_ecs_task_role_name = aws_iam_role.connector_ecs_task.name } sns_topic_arn = local.cloudtrail_sns_arn @@ -121,7 +90,7 @@ module "cloud_scanning" { vpc_subnets = module.ecs_fargate_cluster.vpc_subnets tags = var.tags - depends_on = [local.cloudtrail_sns_arn, module.ecs_fargate_cluster, module.codebuild, module.ssm] + depends_on = [local.cloudtrail_sns_arn, module.ecs_fargate_cluster, module.ssm] } #------------------------------------- @@ -130,6 +99,7 @@ module "cloud_scanning" { module "cloud_bench" { source = "../../modules/services/cloud-bench" + count = var.deploy_bench ? 1 : 0 name = "${var.name}-cloudbench" tags = var.tags diff --git a/examples/organizational/variables.tf b/examples/organizational/variables.tf index b3def878..e3541d14 100644 --- a/examples/organizational/variables.tf +++ b/examples/organizational/variables.tf @@ -68,6 +68,13 @@ variable "benchmark_regions" { default = [] } +variable "deploy_bench" { + type = bool + description = "Whether to deploy or not the cloud benchmarking" + default = true +} + + # # general # diff --git a/examples/single-account-k8s/README.md b/examples/single-account-k8s/README.md index 8ce52604..c82a39bb 100644 --- a/examples/single-account-k8s/README.md +++ b/examples/single-account-k8s/README.md @@ -82,7 +82,6 @@ Notice that: | Name | Source | Version | |------|--------|---------| | [cloud\_connector\_sqs](#module\_cloud\_connector\_sqs) | ../../modules/infrastructure/sqs-sns-subscription | | -| [cloud\_scanning\_sqs](#module\_cloud\_scanning\_sqs) | ../../modules/infrastructure/sqs-sns-subscription | | | [cloudtrail](#module\_cloudtrail) | ../../modules/infrastructure/cloudtrail | | | [codebuild](#module\_codebuild) | ../../modules/infrastructure/codebuild | | | [iam\_user](#module\_iam\_user) | ../../modules/infrastructure/permissions/iam-user | | @@ -94,7 +93,6 @@ Notice that: | Name | Type | |------|------| | [helm_release.cloud_connector](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | -| [helm_release.cloud_scanning](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | ## Inputs diff --git a/examples/single-account-k8s/cloud-connector.tf b/examples/single-account-k8s/cloud-connector.tf index 6b73abcb..01b261b1 100644 --- a/examples/single-account-k8s/cloud-connector.tf +++ b/examples/single-account-k8s/cloud-connector.tf @@ -10,6 +10,16 @@ module "cloud_connector_sqs" { tags = var.tags } +module "codebuild" { + count = var.deploy_image_scanning ? 1 : 0 + source = "../../modules/infrastructure/codebuild" + + secure_api_token_secret_name = module.ssm.secure_api_token_secret_name + + tags = var.tags + # note. this is required to avoid race conditions + depends_on = [module.ssm] +} #------------------------------------- # cloud_connector @@ -50,12 +60,28 @@ resource "helm_release" "cloud_connector" { } values = [ - < [cloud\_bench](#module\_cloud\_bench) | ../../modules/services/cloud-bench | | | [cloud\_connector](#module\_cloud\_connector) | ../../modules/services/cloud-connector | | -| [cloud\_scanning](#module\_cloud\_scanning) | ../../modules/services/cloud-scanning | | | [cloudtrail](#module\_cloudtrail) | ../../modules/infrastructure/cloudtrail | | | [codebuild](#module\_codebuild) | ../../modules/infrastructure/codebuild | | | [ecs\_fargate\_cluster](#module\_ecs\_fargate\_cluster) | ../../modules/infrastructure/ecs-fargate-cluster | | @@ -83,6 +82,7 @@ No resources. | [cloudtrail\_is\_multi\_region\_trail](#input\_cloudtrail\_is\_multi\_region\_trail) | true/false whether cloudtrail will ingest multiregional events | `bool` | `true` | no | | [cloudtrail\_kms\_enable](#input\_cloudtrail\_kms\_enable) | true/false whether cloudtrail delivered events to S3 should persist encrypted | `bool` | `true` | no | | [cloudtrail\_sns\_arn](#input\_cloudtrail\_sns\_arn) | ARN of a pre-existing cloudtrail\_sns. If it does not exist, it will be inferred from created cloudtrail | `string` | `"create"` | no | +| [deploy\_bench](#input\_deploy\_bench) | Whether to deploy or not the cloud benchmarking | `bool` | `true` | no | | [name](#input\_name) | 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 | `string` | `"sfc"` | no | | [sysdig\_secure\_endpoint](#input\_sysdig\_secure\_endpoint) | Sysdig Secure API endpoint | `string` | `"https://secure.sysdig.com"` | no | | [tags](#input\_tags) | sysdig secure-for-cloud tags | `map(string)` |
{
"product": "sysdig-secure-for-cloud"
}
| no | diff --git a/examples/single-account/main.tf b/examples/single-account/main.tf index 40845096..f613a46a 100644 --- a/examples/single-account/main.tf +++ b/examples/single-account/main.tf @@ -1,56 +1,27 @@ #------------------------------------- # general resources #------------------------------------- - module "resource_group" { source = "../../modules/infrastructure/resource-group" name = var.name tags = var.tags } - module "ecs_fargate_cluster" { source = "../../modules/infrastructure/ecs-fargate-cluster" name = var.name tags = var.tags } - module "ssm" { source = "../../modules/infrastructure/ssm" name = var.name sysdig_secure_api_token = var.sysdig_secure_api_token } - #------------------------------------- # cloud-connector #------------------------------------- - -module "cloud_connector" { - source = "../../modules/services/cloud-connector" - name = "${var.name}-cloudconnector" - - sysdig_secure_endpoint = var.sysdig_secure_endpoint - secure_api_token_secret_name = module.ssm.secure_api_token_secret_name - is_organizational = false - - sns_topic_arn = local.cloudtrail_sns_arn - - ecs_cluster = module.ecs_fargate_cluster.id - vpc_id = module.ecs_fargate_cluster.vpc_id - vpc_subnets = module.ecs_fargate_cluster.vpc_subnets - - tags = var.tags - depends_on = [local.cloudtrail_sns_arn, module.ecs_fargate_cluster, module.ssm] -} - - - -#------------------------------------- -# cloud-scanning -#------------------------------------- - module "codebuild" { source = "../../modules/infrastructure/codebuild" name = "${var.name}-codebuild" @@ -61,13 +32,13 @@ module "codebuild" { depends_on = [module.ssm] } - -module "cloud_scanning" { - source = "../../modules/services/cloud-scanning" - name = "${var.name}-cloudscanning" +module "cloud_connector" { + source = "../../modules/services/cloud-connector" + name = "${var.name}-cloudconnector" sysdig_secure_endpoint = var.sysdig_secure_endpoint secure_api_token_secret_name = module.ssm.secure_api_token_secret_name + is_organizational = false build_project_arn = module.codebuild.project_arn build_project_name = module.codebuild.project_name @@ -78,9 +49,9 @@ module "cloud_scanning" { vpc_id = module.ecs_fargate_cluster.vpc_id vpc_subnets = module.ecs_fargate_cluster.vpc_subnets - tags = var.tags - # note. this is required to avoid race conditions - depends_on = [local.cloudtrail_sns_arn, module.ecs_fargate_cluster, module.codebuild, module.ssm] + tags = var.tags + depends_on = [local.cloudtrail_sns_arn, module.ecs_fargate_cluster, module.ssm] + } #------------------------------------- @@ -94,6 +65,7 @@ provider "sysdig" { module "cloud_bench" { source = "../../modules/services/cloud-bench" + count = var.deploy_bench ? 1 : 0 name = "${var.name}-cloudbench" tags = var.tags diff --git a/examples/single-account/variables.tf b/examples/single-account/variables.tf index 91ee19d2..d24acdb3 100644 --- a/examples/single-account/variables.tf +++ b/examples/single-account/variables.tf @@ -40,6 +40,12 @@ variable "benchmark_regions" { default = [] } +variable "deploy_bench" { + type = bool + description = "Whether to deploy or not the cloud benchmarking" + default = true +} + # # general # diff --git a/modules/infrastructure/codebuild/main.tf b/modules/infrastructure/codebuild/main.tf index 0602710e..ffb1191e 100644 --- a/modules/infrastructure/codebuild/main.tf +++ b/modules/infrastructure/codebuild/main.tf @@ -22,15 +22,15 @@ resource "aws_codebuild_project" "build_project" { } source { - type = "NO_SOURCE" - buildspec = < [build\_project\_arn](#input\_build\_project\_arn) | Code Build project arn | `string` | n/a | yes | +| [build\_project\_name](#input\_build\_project\_name) | Code Build project name | `string` | n/a | yes | | [ecs\_cluster](#input\_ecs\_cluster) | ECS Fargate Cluster where deploy the CloudConnector workload | `string` | n/a | yes | | [secure\_api\_token\_secret\_name](#input\_secure\_api\_token\_secret\_name) | Sysdig Secure API token SSM parameter name | `string` | n/a | yes | | [sns\_topic\_arn](#input\_sns\_topic\_arn) | CloudTrail module created SNS Topic ARN | `string` | n/a | yes | @@ -65,7 +75,7 @@ A task deployed on an **ECS deployment** will detect events in your infrastructu | [image](#input\_image) | Image of the cloud connector to deploy | `string` | `"quay.io/sysdig/cloud-connector:latest"` | no | | [is\_organizational](#input\_is\_organizational) | whether secure-for-cloud should be deployed in an organizational setup | `bool` | `false` | no | | [name](#input\_name) | 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 | `string` | `"sfc-cloudconnector"` | no | -| [organizational\_config](#input\_organizational\_config) | organizational\_config. following attributes must be given
|
object({
sysdig_secure_for_cloud_role_arn = string
connector_ecs_task_role_name = string
})
|
{
"connector_ecs_task_role_name": null,
"sysdig_secure_for_cloud_role_arn": null
}
| no | +| [organizational\_config](#input\_organizational\_config) | organizational\_config. following attributes must be given
|
object({
sysdig_secure_for_cloud_role_arn = string
organizational_role_per_account = string
connector_ecs_task_role_name = string
})
|
{
"connector_ecs_task_role_name": null,
"organizational_role_per_account": null,
"sysdig_secure_for_cloud_role_arn": null
}
| no | | [sysdig\_secure\_endpoint](#input\_sysdig\_secure\_endpoint) | Sysdig Secure API endpoint | `string` | `"https://secure.sysdig.com"` | no | | [tags](#input\_tags) | sysdig secure-for-cloud tags | `map(string)` |
{
"product": "sysdig-secure-for-cloud"
}
| no | | [verify\_ssl](#input\_verify\_ssl) | true/false to determine ssl verification for sysdig\_secure\_endpoint | `bool` | `true` | no | diff --git a/modules/services/cloud-connector/ecs-service-security.tf b/modules/services/cloud-connector/ecs-service-security.tf index 5be4fe6f..37c82381 100644 --- a/modules/services/cloud-connector/ecs-service-security.tf +++ b/modules/services/cloud-connector/ecs-service-security.tf @@ -17,6 +17,7 @@ data "aws_iam_role" "task_inherited" { count = var.is_organizational ? 1 : 0 name = var.organizational_config.connector_ecs_task_role_name } + resource "aws_iam_role" "task" { count = var.is_organizational ? 0 : 1 name = "${var.name}-${local.ecs_task_role_name_suffix}" @@ -24,6 +25,7 @@ resource "aws_iam_role" "task" { path = "/" tags = var.tags } + data "aws_iam_policy_document" "task_assume_role" { count = var.is_organizational ? 0 : 1 statement { @@ -70,6 +72,81 @@ data "aws_iam_policy_document" "iam_role_task_policy" { } } +resource "aws_iam_role_policy" "trigger_scan" { + name = "${var.name}-TriggerScan" + role = local.ecs_task_role_id + policy = data.aws_iam_policy_document.trigger_scan.json +} +data "aws_iam_policy_document" "trigger_scan" { + statement { + effect = "Allow" + actions = [ + "codebuild:StartBuild" + ] + resources = [var.build_project_arn] + } +} + +resource "aws_iam_role_policy" "task_definition_reader" { + name = "TaskDefinitionReader" + role = local.ecs_task_role_id + policy = data.aws_iam_policy_document.task_definition_reader.json +} +data "aws_iam_policy_document" "task_definition_reader" { + statement { + effect = "Allow" + actions = [ + "ecs:DescribeTaskDefinition" + ] + resources = ["*"] + } +} + + +resource "aws_iam_role_policy" "secrets_reader" { + name = "SecretsReader" + role = local.ecs_task_role_id + policy = data.aws_iam_policy_document.secrets_reader.json +} + +data "aws_iam_policy_document" "secrets_reader" { + statement { + effect = "Allow" + actions = [ + "kms:Decrypt", + "secretsmanager:GetSecretValue" + ] + resources = ["*"] + } +} + +resource "aws_iam_role_policy" "ecr_reader" { + name = "ECRReader" + role = local.ecs_task_role_id + policy = data.aws_iam_policy_document.ecr_reader.json +} + +data "aws_iam_policy_document" "ecr_reader" { + statement { + effect = "Allow" + actions = [ + "ecr:GetAuthorizationToken", + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + "ecr:GetRepositoryPolicy", + "ecr:DescribeRepositories", + "ecr:ListImages", + "ecr:DescribeImages", + "ecr:BatchGetImage", + "ecr:GetLifecyclePolicy", + "ecr:GetLifecyclePolicyPreview", + "ecr:ListTagsForResource", + "ecr:DescribeImageScanFindings" + ] + resources = ["*"] + } +} + #--------------------------------- # execution role # This role is required by tasks to pull container images and publish container logs to Amazon CloudWatch on your behalf. diff --git a/modules/services/cloud-connector/s3-config.tf b/modules/services/cloud-connector/s3-config.tf index 6fd2aba1..4223a8b0 100644 --- a/modules/services/cloud-connector/s3-config.tf +++ b/modules/services/cloud-connector/s3-config.tf @@ -1,4 +1,3 @@ - locals { s3_bucket_config_id = aws_s3_bucket.s3_config_bucket.id } @@ -11,16 +10,48 @@ resource "aws_s3_bucket_object" "config" { } locals { - default_config = <
  • `sysdig_secure_for_cloud_role_arn` for cloud-connector assumeRole in order to read cloudtrail s3 events
  • and the `connector_ecs_task_role_name` which has been granted trusted-relationship over the secure_for_cloud_role
  • +
      +
    • `sysdig_secure_for_cloud_role_arn` for cloud-connector assumeRole in order to read cloudtrail s3 events
    • +
    • `connector_ecs_task_role_name` which has been granted trusted-relationship over the secure_for_cloud_role
    • +
    • `organizational_role_per_account` is the name of the organizational role deployed by AWS in each account of the organization
    • +
    EOT }