diff --git a/.github/workflows/ci-integration-tests.yaml b/.github/workflows/ci-integration-tests.yaml index eef94e19..2384716e 100644 --- a/.github/workflows/ci-integration-tests.yaml +++ b/.github/workflows/ci-integration-tests.yaml @@ -74,7 +74,12 @@ jobs: TF_VAR_cloudnative_secretAccessKey: ${{ secrets.AWS_QA_CLOUDNATIVE_SECRET_ACCESS_KEY }} TF_VAR_region: ${{secrets.AWS_QA_MANAGED_RESOURCES_REGION }} TF_VAR_cloudtrail_s3_name: ${{ secrets.AWS_QA_MANAGED_CLOUDTRAIL_NAME }} - run: bundle exec kitchen test "organizational-k8s-aws" + run: | + bundle exec kitchen create "organizational-k8s-aws" + bundle exec kitchen converge "organizational-k8s-aws" + bundle exec kitchen setup "organizational-k8s-aws" + bundle exec kitchen verify "organizational-k8s-aws" + bundle exec kitchen destroy "organizational-k8s-aws" - name: Inspect k8s failures if: ${{ failure() }} @@ -139,7 +144,12 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_QA_MANAGED_SECRET_ACCESS_KEY }} AWS_REGION: ${{ secrets.AWS_REGION }} TF_VAR_sysdig_secure_for_cloud_member_account_id: ${{ secrets.AWS_QA_CLOUDNATIVE_ACCOUNT_ID }} - run: bundle exec kitchen test "organizational-aws" + run: | + bundle exec kitchen create "organizational-aws" + bundle exec kitchen converge "organizational-aws" + bundle exec kitchen setup "organizational-aws" + bundle exec kitchen verify "organizational-aws" + bundle exec kitchen destroy "organizational-aws" - name: Destroy organizational resources env: diff --git a/.github/workflows/ci-pull-request.yaml b/.github/workflows/ci-pull-request.yaml index 3ef1793a..2cb7c91a 100644 --- a/.github/workflows/ci-pull-request.yaml +++ b/.github/workflows/ci-pull-request.yaml @@ -9,6 +9,8 @@ on: - master paths: - '**.tf' +env: + GO_VERSION: "^1.17" jobs: getModules: @@ -100,6 +102,10 @@ jobs: uses: actions/checkout@v2 - name: Install Python uses: actions/setup-python@v2 + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: ${{ env.GO_VERSION }} - name: Install Terraform v${{ matrix.version }} uses: hashicorp/setup-terraform@v1 with: @@ -107,7 +113,7 @@ jobs: - name: Install pre-commit dependencies run: | pip install pre-commit - curl -Lo ./terraform-docs.tar.gz https://github.com/terraform-docs/terraform-docs/releases/download/v0.13.0/terraform-docs-v0.13.0-$(uname)-amd64.tar.gz && tar -xzf terraform-docs.tar.gz && chmod +x terraform-docs && sudo mv terraform-docs /usr/bin/ + go install github.com/terraform-docs/terraform-docs@v0.16.0 curl -L "$(curl -s https://api.github.com/repos/terraform-linters/tflint/releases/latest | grep -o -E "https://.+?_linux_amd64.zip")" > tflint.zip && unzip tflint.zip && rm tflint.zip && sudo mv tflint /usr/bin/ - name: Execute pre-commit # Run all pre-commit checks on max version supported diff --git a/.gitignore b/.gitignore index 00e76d13..c9a16e22 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ override.tf.json /lib/bundler/man/ -#Kitchen test +# test .kitchen/* test/fixtures/single-account/.kitchen/ +test/snippets/* diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ac5e1f07..4fe3cf35 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,9 +1,9 @@ # # requirements # - install pre-commit (latest) -# - install terraform-docs (0.13) +# - install terraform-docs (latest) # - see .github/workflows/ci-pull-request.yaml for more info on what's being valiated on CI -# `$ pre-commit run --color=always --show-diff-on-failure --all-files` +# $ pre-commit run --color=always --show-diff-on-failure --all-files # diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md index 4256ccc8..faa18d00 100644 --- a/CONTRIBUTE.md +++ b/CONTRIBUTE.md @@ -59,6 +59,15 @@ We're using **pre-commit** | https://pre-commit.com ``` +- If pre-commit fails on Github but not on your local, try cleaning-up `terraform` files with +```bash +-- resources/terraform-clean.sh +$ find . -name ".terraform" -exec rm -fr {} \; +$ find . -name "terraform.tfstate*" -exec rm -fr {} \; +$ find . -name ".terraform.lock.hcl*" -exec rm -fr {} \; +``` + + ## 2. Check::Integration tests Final user validation. Checks that the snippets for the usage, stated in the official Sysdig Terraform Registry, are working correctly. diff --git a/README.md b/README.md index 485aafa3..a0182307 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Terraform module that deploys the [**Sysdig Secure for Cloud** stack in **AWS**] Provides unified threat-detection, compliance, forensics and analysis through these major components: -* **[CSPM/Compliance](https://docs.sysdig.com/en/docs/sysdig-secure/benchmarks/)**: It evaluates periodically your cloud configuration, using Cloud Custodian, against some benchmarks and returns the results and remediation you need to fix. Managed through `cloud-bench` module.
+* **[CSPM/Compliance](https://docs.sysdig.com/en/docs/sysdig-secure/posture/compliance-unified-/)**: It evaluates periodically your cloud configuration, using Cloud Custodian, against some benchmarks and returns the results and remediation you need to fix. Managed through `cloud-bench` module.
* **[CIEM](https://docs.sysdig.com/en/docs/sysdig-secure/posture/)**: Permissions and Entitlements management. Requires BOTH modules `cloud-connector` and `cloud-bench`.
@@ -41,7 +41,12 @@ For other Cloud providers check: [GCP](https://github.com/sysdiglabs/terraform-g ## Usage -There are several ways to deploy this in you AWS infrastructure: + - There are several ways to deploy this in you AWS infrastructure, gathered under **[`/examples`](./examples)** + - Many module,examples and use-cases provide ways to **re-use existing resources (as optionals)** in your infrastructure (cloudtrail, ecs, vpc, k8s cluster,...) + - Find some real **use-case scenario explanations** under [`/examples-internal/use-cases*`](./examples-internal) + - [Single Account - Existing Cloudtrail](./examples-internal/use-cases-reuse-resources/single-existing-cloudtrail.md) + - [Organizational - Existing Cloudtrail, ECS, VPC, Subnet](./examples-internal/use-cases-reuse-resources/org-existing-cloudtrail-ecs-vpc-subnet.md) + - [Organizational - Existing Cloudtrail withouth SNS, but with S3 configuration, with K8s Cluster and Filtered Cloudtrail Event Account](./examples-internal/use-cases-self-baked/org-s3-k8s-filtered-account.md) ### - Single-Account @@ -135,9 +140,23 @@ Upload any image to the ECR repository of AWS. ## Troubleshooting +### Q: Getting error "404 Invalid parameter: TopicArn" when trying to reuse an existing cloudtrail-sns + +```text +│ Error: error creating SNS Topic Subscription: InvalidParameter: Invalid parameter: TopicArn +│ status code: 400, request id: 1fe94ceb-9f58-5d39-a4df-169f55d25eba +│ +│ with module.cloudvision_aws_single_account.module.cloud_connector.module.cloud_connector_sqs.aws_sns_topic_subscription.this, +│ on ../../../modules/infrastructure/sqs-sns-subscription/main.tf line 6, in resource "aws_sns_topic_subscription" "this": +│ 6: resource "aws_sns_topic_subscription" "this" { -### Q: Getting error when creating the ECS subnet due to nats not being supported ``` + +A: In order to subscribe to a SNS Topic, SQS queue must be in the same region +S: Change `aws provider` `region` variable to match same region for all resources + +### Q: Getting error "400 availabilityZoneId is invalid" when creating the ECS subnet +```text │ Error: error creating subnet: InvalidParameterValue: Value (apne1-az3) for parameter availabilityZoneId is invalid. Subnets can currently only be created in the following availability zones: apne1-az1, apne1-az2, apne1-az4. │ status code: 400, request id: 6e32d757-2e61-4220-8106-22ccf814e1fe │ diff --git a/examples-internal/organizational-k8s-threat-reuse_cloudtrail/README.md b/examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/README.md similarity index 97% rename from examples-internal/organizational-k8s-threat-reuse_cloudtrail/README.md rename to examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/README.md index 2a3b8c1f..e8d520a0 100644 --- a/examples-internal/organizational-k8s-threat-reuse_cloudtrail/README.md +++ b/examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/README.md @@ -81,15 +81,15 @@ Notice that: | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 3.50.0 | -| [helm](#provider\_helm) | >=2.3.0 | +| [aws](#provider\_aws) | 3.74.0 | +| [helm](#provider\_helm) | 2.4.1 | ## Modules | Name | Source | Version | |------|--------|---------| -| [resource\_group](#module\_resource\_group) | ../../modules/infrastructure/resource-group | | -| [ssm](#module\_ssm) | ../../modules/infrastructure/ssm | | +| [resource\_group](#module\_resource\_group) | ../../modules/infrastructure/resource-group | n/a | +| [ssm](#module\_ssm) | ../../modules/infrastructure/ssm | n/a | ## Resources diff --git a/examples-internal/organizational-k8s-threat-reuse_cloudtrail/cloud-connector.tf b/examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/cloud-connector.tf similarity index 100% rename from examples-internal/organizational-k8s-threat-reuse_cloudtrail/cloud-connector.tf rename to examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/cloud-connector.tf diff --git a/examples-internal/organizational-k8s-threat-reuse_cloudtrail/data.tf b/examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/data.tf similarity index 100% rename from examples-internal/organizational-k8s-threat-reuse_cloudtrail/data.tf rename to examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/data.tf diff --git a/examples-internal/organizational-k8s-threat-reuse_cloudtrail/diagram.png b/examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/diagram.png similarity index 100% rename from examples-internal/organizational-k8s-threat-reuse_cloudtrail/diagram.png rename to examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/diagram.png diff --git a/examples-internal/organizational-k8s-threat-reuse_cloudtrail/diagram.py b/examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/diagram.py similarity index 100% rename from examples-internal/organizational-k8s-threat-reuse_cloudtrail/diagram.py rename to examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/diagram.py diff --git a/examples-internal/organizational-k8s-threat-reuse_cloudtrail/main.tf b/examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/main.tf similarity index 100% rename from examples-internal/organizational-k8s-threat-reuse_cloudtrail/main.tf rename to examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/main.tf diff --git a/examples-internal/organizational-k8s-threat-reuse_cloudtrail/outputs.tf b/examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/outputs.tf similarity index 100% rename from examples-internal/organizational-k8s-threat-reuse_cloudtrail/outputs.tf rename to examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/outputs.tf diff --git a/examples-internal/organizational-k8s-threat-reuse_cloudtrail/variables.tf b/examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/variables.tf similarity index 100% rename from examples-internal/organizational-k8s-threat-reuse_cloudtrail/variables.tf rename to examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/variables.tf diff --git a/examples-internal/organizational-k8s-threat-reuse_cloudtrail/versions.tf b/examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/versions.tf similarity index 100% rename from examples-internal/organizational-k8s-threat-reuse_cloudtrail/versions.tf rename to examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3/versions.tf diff --git a/examples-internal/single-account-benchmark/main.tf b/examples-internal/single-account-benchmark/main.tf deleted file mode 100644 index 3a1678fb..00000000 --- a/examples-internal/single-account-benchmark/main.tf +++ /dev/null @@ -1,17 +0,0 @@ -provider "aws" { - region = var.region -} - -provider "sysdig" { - sysdig_secure_url = var.sysdig_secure_endpoint - sysdig_secure_api_token = var.sysdig_secure_api_token - sysdig_secure_insecure_tls = length(regexall("https://.*?\\.sysdig(cloud)?.com/?", var.sysdig_secure_endpoint)) == 1 ? false : true -} - -module "cloud_bench" { - source = "../../modules/services/cloud-bench" - - name = "${var.name}-cloudbench" - tags = var.tags - benchmark_regions = var.benchmark_regions -} diff --git a/examples-internal/single-account-benchmark/outputs.tf b/examples-internal/single-account-benchmark/outputs.tf deleted file mode 100644 index e69de29b..00000000 diff --git a/examples-internal/single-account-benchmark/variables.tf b/examples-internal/single-account-benchmark/variables.tf deleted file mode 100644 index cd9183c4..00000000 --- a/examples-internal/single-account-benchmark/variables.tf +++ /dev/null @@ -1,45 +0,0 @@ -variable "sysdig_secure_api_token" { - sensitive = true - type = string - description = "Sysdig Secure API token" -} - - -#--------------------------------- -# optionals - with defaults -#--------------------------------- - -# -# general -# -variable "region" { - type = string - default = "eu-central-1" - description = "Default region for resource creation in both organization management and secure-for-cloud member account" -} - -variable "sysdig_secure_endpoint" { - type = string - default = "https://secure.sysdig.com" - description = "Sysdig Secure API endpoint" -} - -variable "tags" { - type = map(string) - description = "sysdig secure-for-cloud tags" - default = { - "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 = [] -} - -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" - default = "sfc" -} diff --git a/examples-internal/single-account-benchmark/versions.tf b/examples-internal/single-account-benchmark/versions.tf deleted file mode 100644 index ab0d6a11..00000000 --- a/examples-internal/single-account-benchmark/versions.tf +++ /dev/null @@ -1,12 +0,0 @@ -terraform { - required_version = ">= 0.15.0" - required_providers { - aws = { - version = ">= 3.62.0" - } - sysdig = { - source = "sysdiglabs/sysdig" - version = ">= 0.5.21" - } - } -} diff --git a/examples-internal/single-account-existing-cloudtrail/main.tf b/examples-internal/single-account-existing-cloudtrail/main.tf deleted file mode 100644 index 62104acd..00000000 --- a/examples-internal/single-account-existing-cloudtrail/main.tf +++ /dev/null @@ -1,17 +0,0 @@ -provider "aws" { - region = var.region -} - -module "utils_cloudtrail" { - source = "../../modules/infrastructure/cloudtrail" - name = "${var.name}-single-nocloudtrail" -} - -module "cloudvision_aws_single_account" { - source = "../../examples/single-account" - name = "${var.name}-single-nocloudtrail" - - sysdig_secure_api_token = var.sysdig_secure_api_token - sysdig_secure_endpoint = var.sysdig_secure_endpoint - cloudtrail_sns_arn = module.utils_cloudtrail.sns_topic_arn -} diff --git a/examples-internal/single-account-existing-cloudtrail/outputs.tf b/examples-internal/single-account-existing-cloudtrail/outputs.tf deleted file mode 100644 index e69de29b..00000000 diff --git a/examples-internal/single-account-existing-cloudtrail/variables.tf b/examples-internal/single-account-existing-cloudtrail/variables.tf deleted file mode 100644 index 85ea5bf7..00000000 --- a/examples-internal/single-account-existing-cloudtrail/variables.tf +++ /dev/null @@ -1,23 +0,0 @@ -variable "sysdig_secure_api_token" { - type = string - sensitive = true - description = "Sysdig secure api token" -} - -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" - default = "sfc-tests-kitchen" -} - -variable "region" { - type = string - description = "Region to be deployed" - default = "eu-west-3" -} - -variable "sysdig_secure_endpoint" { - type = string - description = "Sysdig secure endpoint" - default = "https://secure.sysdig.com" -} diff --git a/examples-internal/use-cases-reuse-resources/org-existing-cloudtrail-ecs-vpc-subnet.md b/examples-internal/use-cases-reuse-resources/org-existing-cloudtrail-ecs-vpc-subnet.md new file mode 100644 index 00000000..8bedbee1 --- /dev/null +++ b/examples-internal/use-cases-reuse-resources/org-existing-cloudtrail-ecs-vpc-subnet.md @@ -0,0 +1,123 @@ +# OrganizationSetup - Existing Cloudtrail - Existing ECS/VPC/Subnet + +## Use-Case explanation + +**Client Setup** + +- [X] organizational setup + - [X] organizational cloudtrail + - [X] centralized S3 bucket with cloudtrail-events + - [X] member account usage - all required resources (cloudtrail/s3/sns/sqs for sysdig workload) in same account (managed or specific) (?) + - [ ] member account usage - all required resources are in scattered +- [X] pre-existing resources + - [ ] k8s cluster we want to use to deploy Sysdig for Cloud workload + - [X] pre-existing ECS Cluster/VPC/Subnet we want to use to deploy Sysdig for Cloud workload + +**Sysdig Secure For Cloud Features** + +- [X] Threat Detection + - [X] all accounts of the organization (management account included) +- [ ] Image Scanning (?) + - [ ] ECR pushed images + - [ ] ECS running images +- [ ] CSPM/Compliance (?) +- [ ] CIEM (?) + + + + +## Suggested setup + +For this use-case we're going to use the [`./examples/organizational`](../../examples/organizational/README.md) setup. +In order for this setup to work, several roles and permissions are required. +Before proceeding, please read the example README and check whether you comply with requirements. + +Please contact us if something requires to be adjusted. + + +### Step by Step Example Guide + + + + +0. Configure `AWS_PROFILE` with an organizational Administration credentials + +1. Choose an Organizational **Member account for Sysdig Workload** to be deployed. This accountID will be provided in the `sysdig_secure_for_cloud_member_account_id` parameter + +2. Use `organizational` example with following parameters + + - General + - `AWS_REGION` Same region is to be used for all the following resources, both on the organizational managed account and sysdig workload member account + + - Existing Organizational Cloudtrail Setup + - `cloudtrail_sns_arn` + - `cloudtrail_s3_arn` + - You MUST grant manual permissions to the organizational cloudtrail, for the AWS member-account management role `OrganizationAccountAccessRole` to be able to perform `SNS:Subscribe`. +
This will be required for the CloudConnector SQS Topic subscription. + + - Existing ECS Cluster Workload Setup + - `ecs_cluster_name` ex.: "sfc" + + - Existing Networking Setup + - `ecs_vpc_id` ex.: "vpc-0e91bfef6693f296b" + - `ecs_vpc_subnets_private_ids` Two subnets for the VPC. ex.: "subnet-0c7d803ecdc88437b" + + +### Terraform Manifest Snippet + +```terraform +provider "aws" { + region = "" +} + +module "sysdig-s4c" { + + source = "sysdiglabs/secure-for-cloud/aws//examples/organizational" + name = "sysdig-s4c" + + sysdig_secure_for_cloud_member_account_id="" + + sysdig_secure_api_token = "" + + cloudtrail_sns_arn = "" + cloudtrail_s3_arn = "" + + ecs_cluster_name = "" + ecs_vpc_id = "" + ecs_vpc_subnets_private = ["",""] + +} +``` diff --git a/examples-internal/use-cases-reuse-resources/single-existing-cloudtrail.md b/examples-internal/use-cases-reuse-resources/single-existing-cloudtrail.md new file mode 100644 index 00000000..47a82a30 --- /dev/null +++ b/examples-internal/use-cases-reuse-resources/single-existing-cloudtrail.md @@ -0,0 +1,81 @@ +# SingleAccount - Existing Cloudtrail + +## Use-Case explanation + +**Client Setup** + +- [X] single-account setup +- [X] pre-existing resources + - [X] cloudtrail + - [ ] k8s cluster we want to use to deploy Sysdig for Cloud workload + - [ ] pre-existing ECS Cluster/VPC/Subnet we want to use to deploy Sysdig for Cloud workload + +**Sysdig Secure For Cloud Features** + +- [X] Threat Detection + - [X] all accounts of the organization (management account included) +- [ ] Image Scanning (WIP?) + - [ ] ECR pushed images + - [ ] ECS running images +- [ ] CSPM/Compliance (WIP?) +- [ ] CIEM (WIP?) + +## Suggested setup + +For this use-case we're going to use the [`./examples/single-account`](../../examples/single-account/README.md) setup. +In order for this setup to work, all resources must be in the same AWS account and region. +Before proceeding, please read the example README and check whether you comply with requirements. + +Please contact us if something requires to be adjusted. + +### Step by Step Example Guide + +Use `single-account` example with **`cloudtrail_sns_arn` parameter** + + + + +### Terraform Manifest Snippet + +```terraform` +provider "aws" { + region = +} + +module "sysdig-s4c" { + source = "sysdiglabs/secure-for-cloud/aws//examples/single-account" + name = "sysdig-s4c" + + sysdig_secure_api_token = + cloudtrail_sns_arn = +} +``` diff --git a/examples-internal/self-baked/org-s3-k8s-filtered.md b/examples-internal/use-cases-self-baked/org-s3-k8s-filtered-account.md similarity index 88% rename from examples-internal/self-baked/org-s3-k8s-filtered.md rename to examples-internal/use-cases-self-baked/org-s3-k8s-filtered-account.md index fdd64fbd..c984a12c 100644 --- a/examples-internal/self-baked/org-s3-k8s-filtered.md +++ b/examples-internal/use-cases-self-baked/org-s3-k8s-filtered-account.md @@ -1,19 +1,30 @@ -# ORG-S3-K8S-FILTERED +# OrganizationalSetup - Existing CloudtrailEventsOnS3 - Existing K8s Cluster - Filtered Account ## Use-Case explanation **Current User Setup** + - [X] organizational setup - [ ] organizational cloudtrail - [X] centralized S3 bucket with cloudtrail-events - [ ] member account usage - all required resources (s3/sns/sqs, sysdig workload) in same account - [X] member account usage - all required resources are in scattered -- [X] pre-existing k8s cluster we want to use to deploy Sysdig for Cloud workload +- [X] pre-existing resources + - [X] k8s cluster we want to use to deploy Sysdig for Cloud workload + - [ ] pre-existing ECS Cluster/VPC/Subnet we want to use to deploy Sysdig for Cloud workload + + +**Sysdig Secure For Cloud Features** + +- [X] threat-detection + - [X] account-specific + - [ ] all accounts of the organization (management account included) +- [ ] image-scanning (WIP?) +- [ ] compliance (WIP?) +- [ ] CIEM (WIP?) + +**Other Requirements** -**Sysdig Secure For Cloud Requirements** -- [X] account-specific threat-detection -- [ ] account-specific/organizational? image scanning (WIP) -- [ ] account-specific/organizational? benchmark (WIP) - [X] pre-existing kubernetes management vía service account (WIP)
this has not been tested yet, we rely on an `accessKey` created specifically for Sysdig-For-Cloud. diff --git a/examples/single-account/cloudtrail.tf b/examples/single-account/cloudtrail.tf index 36718e65..3d1c1639 100644 --- a/examples/single-account/cloudtrail.tf +++ b/examples/single-account/cloudtrail.tf @@ -1,6 +1,6 @@ locals { cloudtrail_deploy = var.cloudtrail_sns_arn == "create" - cloudtrail_sns_arn = var.cloudtrail_sns_arn == "create" ? module.cloudtrail[0].sns_topic_arn : var.cloudtrail_sns_arn + cloudtrail_sns_arn = local.cloudtrail_deploy ? module.cloudtrail[0].sns_topic_arn : var.cloudtrail_sns_arn } module "cloudtrail" { diff --git a/examples/single-account/diagram-single.png b/examples/single-account/diagram-single.png index 32d534ec..836330d4 100644 Binary files a/examples/single-account/diagram-single.png and b/examples/single-account/diagram-single.png differ diff --git a/examples/single-account/diagram-single.py b/examples/single-account/diagram-single.py index 862b1361..d3739cec 100644 --- a/examples/single-account/diagram-single.py +++ b/examples/single-account/diagram-single.py @@ -14,79 +14,84 @@ diagram_attr = { - "pad":"0.30" + "pad":"1.25" } + role_attr = { -# "height":"1", -# "width":"0.9", -# "fontsize":"10", + "imagescale":"true", + "width":"2", + "fontsize":"13", } color_event="firebrick" color_scanning = "dark-green" -color_permission="red" +color_permission="steelblue3" color_non_important="gray" color_sysdig="lightblue" with Diagram("Sysdig Secure for Cloud{}(single-account)".format("\n"), graph_attr=diagram_attr, filename="diagram-single", show=True): - with Cluster("AWS account (target)"): + public_registries = Custom("Public Registries","../../resources/diag-registry-icon.png") + + + with Cluster("AWS single-account"): master_credentials = IAM("credentials \npermissions: cloudtrail, role creation,...", fontsize="10") with Cluster("other resources", graph_attr={"bgcolor":"lightblue"}): account_resources = [General("resource-1..n")] - ecr = ECR("container-registry") + ecr = ECR("container-registry\n*sends events on image push to cloudtrail\n*within any account") + + with Cluster("ecs-cluster"): + ecs_services = ElasticContainerServiceService("other services\n*sends events with image runs to cloudtrail") with Cluster("sysdig-secure-for-cloud resources"): # cloudtrail - cloudtrail = Cloudtrail("cloudtrail", shape="plaintext") - cloudtrail_legend = ("for clarity purpose events received from sysdig-secure-for-cloud resources\nhave been removed from diagram, but will be processed too") - Node(label=cloudtrail_legend, width="5",shape="plaintext", labelloc="t", fontsize="10") + cloudtrail = Cloudtrail("cloudtrail\n* ingest events from all\norg member accounts+managed", shape="plaintext") +# cloudtrail_legend = ("for clarity purpose events received from sysdig-secure-for-cloud resources\nhave been removed from diagram, but will be processed too") +# Node(label=cloudtrail_legend, width="5",shape="plaintext", labelloc="t", fontsize="10") cloudtrail_s3 = S3("cloudtrail-s3-events") sns = SNS("cloudtrail-sns-events", comment="i'm a graph") + s3_config = S3("cloud-connector-config") + cloudwatch = Cloudwatch("cloudwatch\n(logs and alarms)") + - cloudtrail >> Edge(color=color_event, style="dashed") >> cloudtrail_s3 >> Edge(color=color_event, style="dashed") >> sns + cloudtrail >> Edge(color=color_event, style="dashed") >> cloudtrail_s3 + cloudtrail >> Edge(color=color_event, style="dashed") >> sns with Cluster("ecs-cluster"): cloud_connector = ElasticContainerServiceService("cloud-connector") - cloud_scanning = ElasticContainerServiceService("cloud-scanning") sqs = SQS("cloudtrail-sqs") - s3_config = S3("cloud-connector-config") - cloudwatch = Cloudwatch("cloudwatch\n(logs and alarms)") - sqs << Edge(color=color_event) << cloud_connector - sqs << Edge(color=color_event) << cloud_scanning cloud_connector - Edge(color=color_non_important) - s3_config cloud_connector >> Edge(color=color_non_important) >> cloudwatch # scanning codebuild = Codebuild("Build-project") - cloud_scanning >> Edge(color=color_non_important) >> cloudwatch - cloud_scanning >> codebuild + cloud_connector >> Edge(color=color_non_important) >> cloudwatch + cloud_connector >> codebuild codebuild >> Edge(color=color_non_important) >> ecr + codebuild >> Edge(color=color_non_important) >> public_registries # bench-role cloud_bench_role = IAMRole("SysdigCloudBench\n(aws:SecurityAudit policy)", **role_attr) - account_resources >> Edge(color=color_event, style="dashed") >> cloudtrail + #account_resources >> Edge(color=color_event, style="dashed") >> cloudtrail sns >> Edge(color=color_event, style="dashed") >> sqs (cloudtrail_s3 << Edge(color=color_non_important)) - cloud_connector - (cloudtrail_s3 << Edge(color=color_non_important)) - cloud_scanning with Cluster("AWS account (sysdig)"): + sds = Custom("Sysdig Secure\n*receives cloud-connector and cloud-build results\n*assumeRole on SysdigCloudBench", "../../resources/diag-sysdig-icon.png") sds_account = General("cloud-bench") - sds = Custom("Sysdig Secure", "../../resources/diag-sysdig-icon.png") - - sds - Edge(label="aws_foundations_bench\n schedule on 0 6 * * *") >> sds_account + sds - Edge(label="aws_foundations_bench\n schedule on rand rand * * *") >> sds_account cloud_connector >> Edge(color=color_sysdig) >> sds codebuild >> Edge(color=color_sysdig) >> sds - sds_account >> Edge(color=color_permission, fontcolor=color_permission, xlabel="assumeRole") >> cloud_bench_role + sds_account >> Edge(color=color_permission, fontcolor=color_permission) >> cloud_bench_role diff --git a/examples/single-account/ecs.tf b/examples/single-account/ecs.tf new file mode 100644 index 00000000..8a065e0b --- /dev/null +++ b/examples/single-account/ecs.tf @@ -0,0 +1,15 @@ +locals { + ecs_deploy = var.ecs_cluster_name == "create" + ecs_cluster_name = local.ecs_deploy ? module.ecs_vpc_secgroup[0].ecs_cluster_name : var.ecs_cluster_name + ecs_vpc_id = local.ecs_deploy ? module.ecs_vpc_secgroup[0].ecs_vpc_id : var.ecs_vpc_id + ecs_vpc_subnets_private_ids = local.ecs_deploy ? module.ecs_vpc_secgroup[0].ecs_vpc_subnets_private_ids : var.ecs_vpc_subnets_private_ids +} + +module "ecs_vpc_secgroup" { + count = local.ecs_deploy ? 1 : 0 + + source = "../../modules/infrastructure/ecs-vpc" + name = var.name + ecs_vpc_region_azs = var.ecs_vpc_region_azs + tags = var.tags +} diff --git a/examples/single-account/main.tf b/examples/single-account/main.tf index 03830ad2..d2d35465 100644 --- a/examples/single-account/main.tf +++ b/examples/single-account/main.tf @@ -7,19 +7,13 @@ module "resource_group" { tags = var.tags } -module "ecs_fargate_cluster" { - source = "../../modules/infrastructure/ecs-fargate-cluster" - name = var.name - ecs_vpc_region_azs = var.ecs_vpc_region_azs - tags = var.tags -} - module "ssm" { source = "../../modules/infrastructure/ssm" name = var.name sysdig_secure_api_token = var.sysdig_secure_api_token } + #------------------------------------- # cloud-connector #------------------------------------- @@ -46,11 +40,12 @@ module "cloud_connector" { 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 + ecs_cluster_name = local.ecs_cluster_name + ecs_vpc_id = local.ecs_vpc_id + ecs_vpc_subnets_private_ids = local.ecs_vpc_subnets_private_ids + tags = var.tags - depends_on = [local.cloudtrail_sns_arn, module.ecs_fargate_cluster, module.ssm] + depends_on = [local.cloudtrail_sns_arn, module.ssm] } diff --git a/examples/single-account/outputs.tf b/examples/single-account/outputs.tf index e69de29b..517bf1ac 100644 --- a/examples/single-account/outputs.tf +++ b/examples/single-account/outputs.tf @@ -0,0 +1,4 @@ +output "cloudtrail_sns_topic_arn" { + value = length(module.cloudtrail) > 0 ? module.cloudtrail[0].sns_topic_arn : var.cloudtrail_sns_arn + description = "ARN of cloudtrail_sns topic" +} diff --git a/examples/single-account/variables.tf b/examples/single-account/variables.tf index eaff5257..b7bd9afb 100644 --- a/examples/single-account/variables.tf +++ b/examples/single-account/variables.tf @@ -16,7 +16,7 @@ variable "sysdig_secure_api_token" { variable "cloudtrail_sns_arn" { type = string default = "create" - description = "ARN of a pre-existing cloudtrail_sns. If it does not exist, it will be inferred from created cloudtrail" + description = "ARN of a pre-existing cloudtrail_sns. If defaulted, a new cloudtrail will be created" } variable "cloudtrail_is_multi_region_trail" { @@ -31,6 +31,39 @@ variable "cloudtrail_kms_enable" { description = "true/false whether cloudtrail delivered events to S3 should persist encrypted" } + +#--------------------------------- +# ecs, security group, vpc +# TODO. convert into an object? +#--------------------------------- + +variable "ecs_cluster_name" { + type = string + default = "create" + description = "Name of a pre-existing ECS (elastic container service) cluster. If defaulted, a new ECS cluster/VPC/Security Group will be created" +} + +variable "ecs_vpc_id" { + type = string + default = "create" + description = "ID of the VPC where the workload is to be deployed. Defaulted to be created when 'ecs_cluster_name' is not provided." +} + +variable "ecs_vpc_subnets_private_ids" { + type = list(string) + default = [] + description = "List of VPC subnets where workload is to be deployed. Defaulted to be created when 'ecs_cluster_name' is not provided." +} + + +variable "ecs_vpc_region_azs" { + type = list(string) + description = "List of Availability Zones for ECS VPC creation. e.g.: [\"apne1-az1\", \"apne1-az2\"]. If defaulted, two of the default 'aws_availability_zones' datasource will be taken" + default = [] +} + + + # # benchmark configuration # @@ -48,17 +81,6 @@ variable "benchmark_regions" { } -# -# ecs vpc configuration -# -variable "ecs_vpc_region_azs" { - type = list(string) - description = "Explicit list of availability zones for ECS VPC creation. eg: [\"apne1-az1\", \"apne1-az2\"]. If left empty it will be defaulted to two from the default datasource" - default = [] -} - - - # # general # diff --git a/modules/infrastructure/cloudtrail/README.md b/modules/infrastructure/cloudtrail/README.md index 34d78e65..87dde203 100644 --- a/modules/infrastructure/cloudtrail/README.md +++ b/modules/infrastructure/cloudtrail/README.md @@ -43,7 +43,7 @@ No modules. | [is\_multi\_region\_trail](#input\_is\_multi\_region\_trail) | true/false whether cloudtrail will ingest multiregional events | `bool` | `true` | 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"` | no | -| [organizational\_config](#input\_organizational\_config) | organizational\_config. following attributes must be given
  • `sysdig_secure_for_cloud_member_account_id` to enable reading permission

  • `organizational_role_per_account` to enable SNS topic subscription
|
object({
sysdig_secure_for_cloud_member_account_id = string
organizational_role_per_account = string
})
|
{
"organizational_role_per_account": null,
"sysdig_secure_for_cloud_member_account_id": null
}
| no | +| [organizational\_config](#input\_organizational\_config) | organizational\_config. following attributes must be given
  • `sysdig_secure_for_cloud_member_account_id` to enable reading permission

  • `organizational_role_per_account` to enable SNS topic subscription. by default "OrganizationAccountAccessRole"
|
object({
sysdig_secure_for_cloud_member_account_id = string
organizational_role_per_account = string
})
|
{
"organizational_role_per_account": null,
"sysdig_secure_for_cloud_member_account_id": null
}
| no | | [s3\_bucket\_expiration\_days](#input\_s3\_bucket\_expiration\_days) | Number of days that the logs will persist in the bucket | `number` | `5` | no | | [tags](#input\_tags) | sysdig secure-for-cloud tags | `map(string)` |
{
"product": "sysdig-secure-for-cloud"
}
| no | @@ -51,8 +51,8 @@ No modules. | Name | Description | |------|-------------| -| [s3\_bucket\_arn](#output\_s3\_bucket\_arn) | Cloudtrail S3 bucket ARN | -| [sns\_topic\_arn](#output\_sns\_topic\_arn) | Cloudtrail SNS topic ARN | +| [s3\_bucket\_arn](#output\_s3\_bucket\_arn) | ARN of Cloudtrail SNS topic | +| [sns\_topic\_arn](#output\_sns\_topic\_arn) | ARN of Cloudtrail SNS topic | ## Authors diff --git a/modules/infrastructure/cloudtrail/outputs.tf b/modules/infrastructure/cloudtrail/outputs.tf index d25fc8e7..1e7cbe86 100644 --- a/modules/infrastructure/cloudtrail/outputs.tf +++ b/modules/infrastructure/cloudtrail/outputs.tf @@ -1,9 +1,9 @@ output "sns_topic_arn" { value = aws_sns_topic.cloudtrail.arn - description = "Cloudtrail SNS topic ARN" + description = "ARN of Cloudtrail SNS topic" } output "s3_bucket_arn" { value = aws_s3_bucket.cloudtrail.arn - description = "Cloudtrail S3 bucket ARN" + description = "ARN of Cloudtrail SNS topic" } diff --git a/modules/infrastructure/cloudtrail/sns.tf b/modules/infrastructure/cloudtrail/sns.tf index 585d8ab3..4646a017 100644 --- a/modules/infrastructure/cloudtrail/sns.tf +++ b/modules/infrastructure/cloudtrail/sns.tf @@ -2,42 +2,3 @@ resource "aws_sns_topic" "cloudtrail" { name = var.name tags = var.tags } - - - -# -------------------------- -# acl -# ------------------------- -resource "aws_sns_topic_policy" "allow_cloudtrail_publish" { - arn = aws_sns_topic.cloudtrail.arn - policy = data.aws_iam_policy_document.cloudtrail_sns.json -} -data "aws_iam_policy_document" "cloudtrail_sns" { - statement { - sid = "AllowCloudtrailPublish" - effect = "Allow" - principals { - identifiers = ["cloudtrail.amazonaws.com"] - type = "Service" - } - actions = ["sns:Publish"] - resources = [aws_sns_topic.cloudtrail.arn] - } - - - # note; this statement is required to be on the SNS creation, - # don't move to other module as policies cannot be overriten/exteneded after creation - dynamic "statement" { - for_each = var.is_organizational ? [1] : [] - content { - sid = "AllowSysdigSecureForCloudSubscribe" - effect = "Allow" - principals { - identifiers = ["arn:aws:iam::${var.organizational_config.sysdig_secure_for_cloud_member_account_id}:role/${var.organizational_config.organizational_role_per_account}"] - type = "AWS" - } - actions = ["sns:Subscribe"] - resources = [aws_sns_topic.cloudtrail.arn] - } - } -} diff --git a/modules/infrastructure/cloudtrail/sns_permissions.tf b/modules/infrastructure/cloudtrail/sns_permissions.tf new file mode 100644 index 00000000..b9129a47 --- /dev/null +++ b/modules/infrastructure/cloudtrail/sns_permissions.tf @@ -0,0 +1,35 @@ +resource "aws_sns_topic_policy" "allow_cloudtrail_publish" { + arn = aws_sns_topic.cloudtrail.arn + policy = data.aws_iam_policy_document.cloudtrail_sns.json +} + + +data "aws_iam_policy_document" "cloudtrail_sns" { + statement { + sid = "AllowCloudtrailPublish" + effect = "Allow" + principals { + identifiers = ["cloudtrail.amazonaws.com"] + type = "Service" + } + actions = ["sns:Publish"] + resources = [aws_sns_topic.cloudtrail.arn] + } + + + # Organizational Requirements + # note; this statement is required to be on the SNS creation, don't move to other module as policies cannot be overriten/exteneded after creation + dynamic "statement" { + for_each = var.is_organizational ? [1] : [] + content { + sid = "AllowSysdigSecureForCloudSubscribe" + effect = "Allow" + principals { + identifiers = ["arn:aws:iam::${var.organizational_config.sysdig_secure_for_cloud_member_account_id}:role/${var.organizational_config.organizational_role_per_account}"] + type = "AWS" + } + actions = ["sns:Subscribe"] + resources = [aws_sns_topic.cloudtrail.arn] + } + } +} diff --git a/modules/infrastructure/cloudtrail/variables.tf b/modules/infrastructure/cloudtrail/variables.tf index 9f274785..71bb140f 100644 --- a/modules/infrastructure/cloudtrail/variables.tf +++ b/modules/infrastructure/cloudtrail/variables.tf @@ -25,8 +25,7 @@ variable "organizational_config" { description = <<-EOT organizational_config. following attributes must be given
  • `sysdig_secure_for_cloud_member_account_id` to enable reading permission
  • -
  • `organizational_role_per_account` to enable SNS topic subscription
- +
  • `organizational_role_per_account` to enable SNS topic subscription. by default "OrganizationAccountAccessRole"
  • EOT } diff --git a/modules/infrastructure/cloudtrail_s3-sns-sqs/README.md b/modules/infrastructure/cloudtrail_s3-sns-sqs/README.md index d76323b8..fcad6776 100644 --- a/modules/infrastructure/cloudtrail_s3-sns-sqs/README.md +++ b/modules/infrastructure/cloudtrail_s3-sns-sqs/README.md @@ -43,8 +43,8 @@ EVENT FILTER/fine-tunning, regarding what we want to send to Sysdig Cloud-Connec | Name | Source | Version | |------|--------|---------| -| [cloudtrail\_s3\_sns\_sqs](#module\_cloudtrail\_s3\_sns\_sqs) | ../sqs-sns-subscription | | -| [resource\_group](#module\_resource\_group) | ../resource-group | | +| [cloudtrail\_s3\_sns\_sqs](#module\_cloudtrail\_s3\_sns\_sqs) | ../sqs-sns-subscription | n/a | +| [resource\_group](#module\_resource\_group) | ../resource-group | n/a | ## Resources diff --git a/modules/infrastructure/ecs-fargate-cluster/outputs.tf b/modules/infrastructure/ecs-fargate-cluster/outputs.tf deleted file mode 100644 index 6816ff9f..00000000 --- a/modules/infrastructure/ecs-fargate-cluster/outputs.tf +++ /dev/null @@ -1,15 +0,0 @@ -output "id" { - value = aws_ecs_cluster.ecs_cluster.id - description = "ECS Cluster ID" -} - - -output "vpc_id" { - value = module.vpc.vpc_id - description = "vpc id" -} - -output "vpc_subnets" { - value = module.vpc.private_subnets - description = "vpc privates subnets" -} diff --git a/modules/infrastructure/ecs-fargate-cluster/versions.tf b/modules/infrastructure/ecs-fargate-cluster/versions.tf deleted file mode 100644 index ed2c3cdc..00000000 --- a/modules/infrastructure/ecs-fargate-cluster/versions.tf +++ /dev/null @@ -1,8 +0,0 @@ -terraform { - required_version = ">= 0.15.0" - required_providers { - aws = { - version = ">= 3.50.0" - } - } -} diff --git a/modules/infrastructure/ecs-fargate-cluster/README.md b/modules/infrastructure/ecs-vpc/README.md similarity index 70% rename from modules/infrastructure/ecs-fargate-cluster/README.md rename to modules/infrastructure/ecs-vpc/README.md index 4da21c04..2b1e4086 100644 --- a/modules/infrastructure/ecs-fargate-cluster/README.md +++ b/modules/infrastructure/ecs-vpc/README.md @@ -1,4 +1,4 @@ -# AWS ECS Cluster deployment module +# ECS Cluster / VPC / SecGroup @@ -19,7 +19,7 @@ | Name | Source | Version | |------|--------|---------| -| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | n/a | ## Resources @@ -32,7 +32,7 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [ecs\_vpc\_region\_azs](#input\_ecs\_vpc\_region\_azs) | Explicit list of availability zones for VPC creation. eg: ["apne1-az1", "apne1-az2"]. If left empty it will be defaulted to two from the default datasource | `list(string)` | `[]` | no | +| [ecs\_vpc\_region\_azs](#input\_ecs\_vpc\_region\_azs) | List of Availability Zones for ECS VPC creation. e.g.: ["apne1-az1", "apne1-az2"]. If defaulted, two of the default 'aws\_availability\_zones' datasource will be taken | `list(string)` | `[]` | 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 | | [tags](#input\_tags) | sysdig secure-for-cloud tags | `map(string)` |
    {
    "product": "sysdig-secure-for-cloud"
    }
    | no | @@ -40,9 +40,9 @@ | Name | Description | |------|-------------| -| [id](#output\_id) | ECS Cluster ID | -| [vpc\_id](#output\_vpc\_id) | vpc id | -| [vpc\_subnets](#output\_vpc\_subnets) | vpc privates subnets | +| [ecs\_cluster\_name](#output\_ecs\_cluster\_name) | ID of the ECS cluster | +| [ecs\_vpc\_id](#output\_ecs\_vpc\_id) | ID of the VPC for the ECS cluster | +| [ecs\_vpc\_subnets\_private\_ids](#output\_ecs\_vpc\_subnets\_private\_ids) | IDs of the private subnets of the VPC for the ECS cluster | ## Authors diff --git a/modules/infrastructure/ecs-fargate-cluster/main.tf b/modules/infrastructure/ecs-vpc/main.tf similarity index 100% rename from modules/infrastructure/ecs-fargate-cluster/main.tf rename to modules/infrastructure/ecs-vpc/main.tf diff --git a/modules/infrastructure/ecs-vpc/outputs.tf b/modules/infrastructure/ecs-vpc/outputs.tf new file mode 100644 index 00000000..5d54e639 --- /dev/null +++ b/modules/infrastructure/ecs-vpc/outputs.tf @@ -0,0 +1,14 @@ +output "ecs_cluster_name" { + value = aws_ecs_cluster.ecs_cluster.id + description = "ID of the ECS cluster" +} + +output "ecs_vpc_id" { + value = module.vpc.vpc_id + description = "ID of the VPC for the ECS cluster" +} + +output "ecs_vpc_subnets_private_ids" { + value = module.vpc.private_subnets + description = "IDs of the private subnets of the VPC for the ECS cluster" +} diff --git a/modules/infrastructure/ecs-fargate-cluster/variables.tf b/modules/infrastructure/ecs-vpc/variables.tf similarity index 76% rename from modules/infrastructure/ecs-fargate-cluster/variables.tf rename to modules/infrastructure/ecs-vpc/variables.tf index 4e9f6cf9..391556e6 100644 --- a/modules/infrastructure/ecs-fargate-cluster/variables.tf +++ b/modules/infrastructure/ecs-vpc/variables.tf @@ -5,13 +5,13 @@ # # vpc configuration # + variable "ecs_vpc_region_azs" { type = list(string) - description = "Explicit list of availability zones for VPC creation. eg: [\"apne1-az1\", \"apne1-az2\"]. If left empty it will be defaulted to two from the default datasource" + description = "List of Availability Zones for ECS VPC creation. e.g.: [\"apne1-az1\", \"apne1-az2\"]. If defaulted, two of the default 'aws_availability_zones' datasource will be taken" default = [] } - # # general # diff --git a/examples-internal/single-account-existing-cloudtrail/versions.tf b/modules/infrastructure/ecs-vpc/versions.tf similarity index 100% rename from examples-internal/single-account-existing-cloudtrail/versions.tf rename to modules/infrastructure/ecs-vpc/versions.tf diff --git a/modules/infrastructure/ecs-fargate-cluster/vpc.tf b/modules/infrastructure/ecs-vpc/vpc.tf similarity index 87% rename from modules/infrastructure/ecs-fargate-cluster/vpc.tf rename to modules/infrastructure/ecs-vpc/vpc.tf index eda475c5..83166f04 100644 --- a/modules/infrastructure/ecs-fargate-cluster/vpc.tf +++ b/modules/infrastructure/ecs-vpc/vpc.tf @@ -1,7 +1,7 @@ data "aws_availability_zones" "zones" { } - +# https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest module "vpc" { source = "terraform-aws-modules/vpc/aws" diff --git a/modules/infrastructure/permissions/iam-user/README.md b/modules/infrastructure/permissions/iam-user/README.md index 48f67766..f4009241 100644 --- a/modules/infrastructure/permissions/iam-user/README.md +++ b/modules/infrastructure/permissions/iam-user/README.md @@ -21,9 +21,9 @@ Creates an IAM user and adds permissions for required modules. | Name | Source | Version | |------|--------|---------| -| [credentials\_cloud\_connector](#module\_credentials\_cloud\_connector) | ../cloud-connector | | -| [credentials\_cloud\_scanning](#module\_credentials\_cloud\_scanning) | ../cloud-scanning | | -| [credentials\_general](#module\_credentials\_general) | ../general | | +| [credentials\_cloud\_connector](#module\_credentials\_cloud\_connector) | ../cloud-connector | n/a | +| [credentials\_cloud\_scanning](#module\_credentials\_cloud\_scanning) | ../cloud-scanning | n/a | +| [credentials\_general](#module\_credentials\_general) | ../general | n/a | ## Resources diff --git a/modules/services/cloud-bench/README.md b/modules/services/cloud-bench/README.md index 7e16734b..7ce06b8d 100644 --- a/modules/services/cloud-bench/README.md +++ b/modules/services/cloud-bench/README.md @@ -1,12 +1,15 @@ # Cloud Bench deploy in AWS Module -Deploys + +Deployed on the **target AWS account(s)**: - The required IAM Role and IAM Policies (`arn:aws:iam::aws:policy/SecurityAudit`) to allow Sysdig to run AWS Benchmarks on your behalf. -- The required provisioning on Sysdig Backend to use this ExternalId-based, AssumeRole permissions. -- An `aws_foundations_bench-1.3.0` benchmak task schedule on a random hour of the day `rand rand * * *` -- Organizational deploymetn vía `aws_cloudformation_stack_set` to generate required role/policies on member accounts + - A Sysdig provided `ExternalId` will be used. + - This is done using `aws_cloudformation_stack_set`. +Deployed on **Sysdig Backend** +- The required provisioning on Sysdig Backend to use the `ExternalId`-basedIAM Role with an AssumeRole. +- An `aws_foundations_bench-1.3.0` benchmak task schedule on a random hour of the day `rand rand * * *` diff --git a/modules/services/cloud-connector/README.md b/modules/services/cloud-connector/README.md index 620f039c..1558ae83 100644 --- a/modules/services/cloud-connector/README.md +++ b/modules/services/cloud-connector/README.md @@ -20,7 +20,7 @@ A task deployed on an **ECS deployment** will detect events in your infrastructu | Name | Source | Version | |------|--------|---------| -| [cloud\_connector\_sqs](#module\_cloud\_connector\_sqs) | ../../infrastructure/sqs-sns-subscription | | +| [cloud\_connector\_sqs](#module\_cloud\_connector\_sqs) | ../../infrastructure/sqs-sns-subscription | n/a | ## Resources @@ -44,7 +44,7 @@ A task deployed on an **ECS deployment** will detect events in your infrastructu | [aws_s3_bucket_public_access_block.s3_config_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource | | [aws_security_group.sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | | [aws_caller_identity.me](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | -| [aws_ecs_cluster.ecs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecs_cluster) | data source | +| [aws_ecs_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecs_cluster) | data source | | [aws_iam_policy_document.ecr_reader](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.execution](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.execution_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | @@ -64,13 +64,13 @@ A task deployed on an **ECS deployment** will detect events in your infrastructu |------|-------------|------|---------|:--------:| | [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) | ARN of a cloudtrail-sns topic | `string` | n/a | yes | -| [vpc\_id](#input\_vpc\_id) | VPC where the workload is deployed | `string` | n/a | yes | -| [vpc\_subnets](#input\_vpc\_subnets) | Subnets where the CloudConnector will be deployed | `list(string)` | n/a | yes | | [cloudwatch\_log\_retention](#input\_cloudwatch\_log\_retention) | Days to keep logs for CloudConnector | `number` | `5` | no | | [connector\_ecs\_task\_role\_name](#input\_connector\_ecs\_task\_role\_name) | Default ecs cloudconnector task role name | `string` | `"ECSTaskRole"` | no | +| [ecs\_cluster\_name](#input\_ecs\_cluster\_name) | Name of a pre-existing ECS (elastic container service) cluster. If defaulted, a new ECS cluster/VPC/Security Group will be created | `string` | `"create"` | no | +| [ecs\_vpc\_id](#input\_ecs\_vpc\_id) | ID of the VPC where the workload is to be deployed. If defaulted, one will be created | `string` | `"create"` | no | +| [ecs\_vpc\_subnets\_private\_ids](#input\_ecs\_vpc\_subnets\_private\_ids) | List of VPC subnets where workload is to be deployed. Defaulted to be created when 'ecs\_cluster\_name' is not provided. | `list(string)` | `[]` | no | | [extra\_env\_vars](#input\_extra\_env\_vars) | Extra environment variables for the Cloud Connector deployment | `map(string)` | `{}` | no | | [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 | diff --git a/modules/services/cloud-connector/ecs-service.tf b/modules/services/cloud-connector/ecs-service.tf index 45fd0d2f..551deafa 100644 --- a/modules/services/cloud-connector/ecs-service.tf +++ b/modules/services/cloud-connector/ecs-service.tf @@ -1,18 +1,18 @@ -data "aws_ecs_cluster" "ecs" { - cluster_name = var.ecs_cluster +data "aws_ecs_cluster" "this" { + cluster_name = var.ecs_cluster_name } - resource "aws_ecs_service" "service" { - name = var.name - cluster = data.aws_ecs_cluster.ecs.id - desired_count = 1 - launch_type = "FARGATE" + name = var.name + cluster = data.aws_ecs_cluster.this.id network_configuration { - subnets = var.vpc_subnets + subnets = var.ecs_vpc_subnets_private_ids security_groups = [aws_security_group.sg.id] } + + desired_count = 1 + launch_type = "FARGATE" task_definition = aws_ecs_task_definition.task_definition.arn tags = var.tags } diff --git a/modules/services/cloud-connector/ecs-service-security.tf b/modules/services/cloud-connector/permissions.tf similarity index 100% rename from modules/services/cloud-connector/ecs-service-security.tf rename to modules/services/cloud-connector/permissions.tf diff --git a/modules/services/cloud-connector/sec-group.tf b/modules/services/cloud-connector/sec-group.tf index 5839b782..2d9a2207 100644 --- a/modules/services/cloud-connector/sec-group.tf +++ b/modules/services/cloud-connector/sec-group.tf @@ -1,15 +1,16 @@ resource "aws_security_group" "sg" { - vpc_id = var.vpc_id name = var.name description = "CloudConnector workload Security Group" + vpc_id = var.ecs_vpc_id + # allow all (protocol -1, from 0, to 0) - ingress { - from_port = 0 - protocol = "-1" - to_port = 0 - cidr_blocks = ["0.0.0.0/0"] - } + # ingress { + # from_port = 0 + # protocol = "-1" + # to_port = 0 + # cidr_blocks = ["0.0.0.0/0"] + # } # allow all egress { diff --git a/modules/services/cloud-connector/variables.tf b/modules/services/cloud-connector/variables.tf index 6b0390ac..deafe29d 100644 --- a/modules/services/cloud-connector/variables.tf +++ b/modules/services/cloud-connector/variables.tf @@ -1,8 +1,3 @@ -variable "ecs_cluster" { - type = string - description = "ECS Fargate Cluster where deploy the CloudConnector workload" -} - variable "secure_api_token_secret_name" { type = string description = "Sysdig Secure API token SSM parameter name" @@ -20,18 +15,27 @@ variable "build_project_name" { #--------------------------------- -# vpc +# ecs, security group, vpc +# TODO. convert into an object? #--------------------------------- -variable "vpc_id" { + +variable "ecs_cluster_name" { type = string - description = "VPC where the workload is deployed" + default = "create" + description = "Name of a pre-existing ECS (elastic container service) cluster. If defaulted, a new ECS cluster/VPC/Security Group will be created" } -variable "vpc_subnets" { - type = list(string) - description = "Subnets where the CloudConnector will be deployed" +variable "ecs_vpc_id" { + type = string + default = "create" + description = "ID of the VPC where the workload is to be deployed. If defaulted, one will be created" } +variable "ecs_vpc_subnets_private_ids" { + type = list(string) + default = [] + description = "List of VPC subnets where workload is to be deployed. Defaulted to be created when 'ecs_cluster_name' is not provided." +} #--------------------------------- # cloud-connector parametrization @@ -83,7 +87,6 @@ variable "organizational_config" { # # module config # - variable "connector_ecs_task_role_name" { type = string default = "ECSTaskRole" diff --git a/resources/diag-registry-icon.png b/resources/diag-registry-icon.png new file mode 100644 index 00000000..3380e2ce Binary files /dev/null and b/resources/diag-registry-icon.png differ diff --git a/resources/terraform-clean.sh b/resources/terraform-clean.sh new file mode 100755 index 00000000..08378767 --- /dev/null +++ b/resources/terraform-clean.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +cd .. +find . -name ".terraform" -exec rm -fr {} \; +find . -name "terraform.tfstate*" -exec rm -fr {} \; +find . -name ".terraform.lock.hcl*" -exec rm -fr {} \; diff --git a/test/fixtures/organizational-k8s/main.tf b/test/fixtures/organizational-k8s/main.tf index cae2ac5f..6c694a79 100644 --- a/test/fixtures/organizational-k8s/main.tf +++ b/test/fixtures/organizational-k8s/main.tf @@ -56,7 +56,7 @@ module "org_k8s_threat_reuse_cloudtrail" { providers = { aws = aws.cloudnative } - source = "../../../examples-internal/organizational-k8s-threat-reuse_cloudtrail" + source = "../../../examples-internal/organizational-k8s-threat-reuse_cloudtrail_s3" name = "${var.name}-orgk8s" sysdig_secure_api_token = var.sysdig_secure_api_token diff --git a/test/fixtures/organizational/main.tf b/test/fixtures/organizational/main.tf index 98537458..553349ab 100644 --- a/test/fixtures/organizational/main.tf +++ b/test/fixtures/organizational/main.tf @@ -6,8 +6,6 @@ module "cloudvision_aws_organizational" { source = "../../../examples/organizational" name = "${var.name}-org" - region = var.region - sysdig_secure_api_token = var.sysdig_secure_api_token sysdig_secure_endpoint = var.sysdig_secure_endpoint sysdig_secure_for_cloud_member_account_id = var.sysdig_secure_for_cloud_member_account_id