├── .github ├── dependabot.yml ├── pull_request_template.md └── workflows │ └── security-considerations.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .yamlfmt ├── CODEOWNERS ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── SECURITY.md ├── bootstrap_and_teardown.md ├── bosh ├── opsfiles │ ├── basic-auth.yml │ ├── bootstrap-instance-size.yml │ ├── iam-instance-profile.yml │ ├── self-signed-tls.yml │ ├── ssh-tunnel.yml │ └── vip-network.yml └── varsfiles │ ├── collect-aws-variables.yml │ ├── deploy-bosh.yml │ └── secret-rotation.yml ├── ci ├── check-certificates.sh ├── check-certificates.yml ├── concourse-defaults.yml ├── credentials.yml.example ├── delete-old-certificates.sh ├── delete-old-certificates.yml ├── pipeline.yml ├── provision-certificate.sh ├── provision-certificate.yml ├── scripts │ ├── create-and-update-db.sh │ ├── terraform_fmt.sh │ └── update-db.sh ├── upload-certificate.sh ├── upload-certificate.yml └── waf-tests │ ├── requirements.txt │ ├── test-waf-rules.sh │ ├── test-waf-rules.yml │ └── test_waf_rules.py ├── docs ├── README.md └── WAFRules.md ├── env.example.sh ├── scripts ├── add_environment │ ├── README.md │ ├── env.example.sh │ └── manage_environment.sh ├── bootstrap.sh ├── bootstrap │ ├── 01-bootstrap-terraform.sh │ ├── 02-bootstrap-concourse.sh │ ├── 03-main-terraform.sh │ ├── 04-bootstrap-terraform-peering.sh │ ├── 05-generate-secrets.sh │ ├── 06-deploy-bosh.sh │ ├── 07-deploy-concourse.sh │ ├── destroy-02-bootstrap-concourse.sh │ ├── setup-bootstrap.sh │ └── teardown.sh ├── environment.default.sh ├── run-plan.sh └── update-dependabot.sh ├── terraform ├── modules │ ├── autoscaler │ │ ├── database.tf │ │ ├── outputs.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── bosh_vpc │ │ ├── ec2.tf │ │ ├── endpoint_s3.tf │ │ ├── network_private.tf │ │ ├── network_public.tf │ │ ├── outputs.tf │ │ ├── sg_bosh.tf │ │ ├── sg_local_vpc_traffic.tf │ │ ├── sg_restricted_web_traffic.tf │ │ ├── sg_web_traffic.tf │ │ ├── variables.tf │ │ ├── versions.tf │ │ └── vpc.tf │ ├── bosh_vpc_v2 │ │ ├── ec2.tf │ │ ├── endpoint_s3.tf │ │ ├── network_private.tf │ │ ├── network_public.tf │ │ ├── outputs.tf │ │ ├── sg_bosh.tf │ │ ├── sg_local_vpc_traffic.tf │ │ ├── sg_restricted_web_traffic.tf │ │ ├── sg_web_traffic.tf │ │ ├── variables.tf │ │ ├── versions.tf │ │ └── vpc.tf │ ├── cdn_broker │ │ ├── outputs.tf │ │ ├── resources.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── cloudfoundry │ │ ├── buckets.tf │ │ ├── database.tf │ │ ├── elb_apps.tf │ │ ├── elb_main.tf │ │ ├── elb_uaa.tf │ │ ├── elb_waf.tf │ │ ├── nlb.tf │ │ ├── outputs.tf │ │ ├── service_subnets.tf │ │ ├── variables.tf │ │ ├── versions.tf │ │ └── waf.tf │ ├── cloudfront │ │ ├── distribution.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── cloudwatch │ │ ├── alarms.tf │ │ ├── dashboards.tf │ │ ├── policies.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── concourse │ │ ├── elb.tf │ │ ├── network.tf │ │ ├── outputs.tf │ │ ├── rds.tf │ │ ├── sg_concourse.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── concourse_v2 │ │ ├── elb.tf │ │ ├── network.tf │ │ ├── outputs.tf │ │ ├── rds.tf │ │ ├── sg_concourse.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── credhub │ │ ├── alb.tf │ │ ├── network.tf │ │ ├── outputs.tf │ │ ├── rds.tf │ │ ├── security-groups.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── credhub_v2 │ │ ├── alb.tf │ │ ├── network.tf │ │ ├── outputs.tf │ │ ├── rds.tf │ │ ├── security-groups.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── csb │ │ ├── README.md │ │ ├── broker │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ └── iam │ │ │ ├── commercial │ │ │ ├── csb.tf │ │ │ ├── outputs.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ │ └── govcloud │ │ │ ├── concourse.tf │ │ │ ├── csb.tf │ │ │ ├── csb_helper.tf │ │ │ ├── ecr.tf │ │ │ ├── outputs.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ ├── cvd_mirror │ │ ├── public_encrypted_bucket.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── cvd_mirror_v2 │ │ ├── public_encrypted_bucket.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── defect_dojo │ │ ├── elb.tf │ │ ├── network.tf │ │ ├── outputs.tf │ │ ├── rds.tf │ │ ├── security-groups.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── diego │ │ ├── diego_elb_main.tf │ │ ├── outputs.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── dns │ │ ├── outputs.tf │ │ ├── sg.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── dns_logging │ │ ├── resolver_logging.tf │ │ └── variables.tf │ ├── elasticache_broker_network │ │ ├── elb.tf │ │ ├── outputs.tf │ │ ├── sg_redis.tf │ │ ├── subnets.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── elasticache_replication_group │ │ ├── elasticache.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── elasticsearch_broker │ │ ├── log_group.tf │ │ ├── outputs.tf │ │ ├── security_group.tf │ │ ├── subnets.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── environment_dns │ │ ├── dns.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── external_domain_broker │ │ ├── cloudwatch.tf │ │ ├── iam.tf │ │ ├── outputs.tf │ │ ├── route53.tf │ │ ├── s3.tf │ │ ├── variables.tf │ │ ├── versions.tf │ │ └── waf.tf │ ├── external_domain_broker_govcloud │ │ ├── iam.tf │ │ ├── outputs.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── external_domain_broker_loadbalancer_group │ │ ├── outputs.tf │ │ ├── resources.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── external_domain_broker_tests │ │ ├── outputs.tf │ │ ├── resources.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── iam_role │ │ ├── outputs.tf │ │ ├── role.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── iam_role_policy │ │ ├── aws_broker │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── blobstore │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── bosh │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── bosh_compilation │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── cf_blobstore │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── cloudwatch │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── compliance_role │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── concourse_iaas_worker │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── concourse_worker │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── ecr │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── elasticache_broker │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── logs_opensearch_ingestor │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── logs_opensearch_metric_ingestor │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── logs_opensearch_s3_ingestor │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── logsearch_ingestor │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── s3_broker │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── s3_broker_task │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ └── self_managed_credentials │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ ├── iam_user │ │ ├── billing_user │ │ │ ├── outputs.tf │ │ │ ├── user.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── cvd_sync │ │ │ ├── outputs.tf │ │ │ ├── user.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── ecr_pull_user │ │ │ ├── outputs.tf │ │ │ ├── policy.tftpl │ │ │ ├── user.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── ecr_user │ │ │ ├── outputs.tf │ │ │ ├── user.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── health_check │ │ │ ├── outputs.tf │ │ │ ├── user.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── iam_cert_provision │ │ │ ├── outputs.tf │ │ │ ├── user.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── lets_encrypt │ │ │ ├── outputs.tf │ │ │ ├── user.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── limit_check_user │ │ │ ├── outputs.tf │ │ │ ├── user.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── rds_storage_alert │ │ │ ├── outputs.tf │ │ │ ├── user.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── s3_bucket_readonly │ │ │ ├── outputs.tf │ │ │ ├── user.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── s3_logstash │ │ │ ├── outputs.tf │ │ │ ├── user.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ └── terraform_provision │ │ │ ├── outputs.tf │ │ │ ├── user.tf │ │ │ └── versions.tf │ ├── jumpbox │ │ ├── jumpbox.tf │ │ ├── outputs.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── log_bucket │ │ ├── log_bucket.tf │ │ ├── outputs.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── log_bucket_v2 │ │ ├── log_bucket.tf │ │ ├── outputs.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── logsearch │ │ ├── elb.tf │ │ ├── elb_platform_kibana.tf │ │ ├── elb_platform_syslog.tf │ │ ├── outputs.tf │ │ ├── platform_log_bucket.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── monitoring │ │ ├── elb.tf │ │ ├── network.tf │ │ ├── outputs.tf │ │ ├── sg_monitoring.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── monitoring_v2 │ │ ├── elb.tf │ │ ├── network.tf │ │ ├── outputs.tf │ │ ├── sg_monitoring.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── rds │ │ ├── database.tf │ │ ├── outputs.tf │ │ ├── parameter_group.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── rds_network │ │ ├── network.tf │ │ ├── outputs.tf │ │ ├── sg_mssql.tf │ │ ├── sg_mysql.tf │ │ ├── sg_oracle.tf │ │ ├── sg_postgres.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── rds_network_v2 │ │ ├── network.tf │ │ ├── outputs.tf │ │ ├── sg_mssql.tf │ │ ├── sg_mysql.tf │ │ ├── sg_oracle.tf │ │ ├── sg_postgres.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── regionalmaster_dns │ │ ├── dns.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── s3_bucket │ │ ├── encrypted_bucket │ │ │ ├── encrypted_bucket.tf │ │ │ ├── outputs.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── encrypted_bucket_v2 │ │ │ ├── encrypted_bucket.tf │ │ │ ├── outputs.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── kms_encrypted_bucket │ │ │ ├── bucket.tf │ │ │ ├── iam.tf │ │ │ ├── kms.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ ├── log_encrypted_bucket │ │ │ ├── log_encrypted_bucket.tf │ │ │ ├── outputs.tf │ │ │ ├── policy.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── public_encrypted_bucket │ │ │ ├── public_encrypted_bucket.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ └── semver_bucket │ │ │ ├── bucket.tf │ │ │ ├── output.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ ├── shibboleth │ │ ├── outputs.tf │ │ ├── shibboleth_elb_main.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── smtp │ │ ├── outputs.tf │ │ ├── sg.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── sns │ │ ├── outputs.tf │ │ ├── sns.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── stack │ │ ├── base │ │ │ ├── base.tf │ │ │ ├── outputs.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ ├── base_v2 │ │ │ ├── base.tf │ │ │ ├── outputs.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ │ └── spoke │ │ │ ├── outputs.tf │ │ │ ├── spoke.tf │ │ │ ├── variables.tf │ │ │ └── versions.tf │ ├── test_cdn_dns │ │ ├── dns.tf │ │ └── variables.tf │ ├── vpc_peering │ │ ├── network.tf │ │ ├── outputs.tf │ │ ├── variables.tf │ │ └── versions.tf │ └── vpc_peering_sg │ │ ├── modify_bosh_sg.tf │ │ ├── variables.tf │ │ └── versions.tf └── stacks │ ├── bootstrap-westa-hub │ ├── README.md │ ├── bootstrap.tf │ ├── buckets.tf │ ├── outputs.tf │ ├── variables.tf │ └── versions.tf │ ├── bootstrap │ ├── README.md │ ├── bootstrap.tf │ ├── outputs.tf │ ├── peering.tf │ ├── variables.tf │ └── versions.tf │ ├── concourse │ ├── teams.tf │ └── variables.tf │ ├── dns-westa-hub │ ├── README.md │ ├── outputs.tf │ ├── remote_state.tf │ ├── stacks.tf │ ├── variables.tf │ ├── versions.tf │ ├── westa-hub-stage.tf │ └── westa-hub.tf │ ├── dns │ ├── dev-tooling.tf │ ├── dev.tf │ ├── outputs.tf │ ├── pages.tf │ ├── production.tf │ ├── stack.tf │ ├── staging-health-checks.tf │ ├── staging-tooling.tf │ ├── staging.tf │ ├── tooling.tf │ ├── validators.tf │ └── versions.tf │ ├── ecr │ ├── outputs.tf │ ├── stack.tf │ ├── variables.tf │ └── versions.tf │ ├── external │ ├── outputs.tf │ ├── stack.tf │ ├── variables.tf │ └── versions.tf │ ├── main │ ├── buckets.tf │ ├── domains_broker.tf │ ├── iam.tf │ ├── outputs.tf │ ├── stack.tf │ ├── variables.tf │ └── versions.tf │ ├── managedaccount │ ├── .terraform.lock.hcl │ ├── iam.tf │ ├── outputs.tf │ ├── variables.tf │ └── versions.tf │ ├── regionalmasterbosh │ ├── buckets.tf │ ├── elb_uaa.tf │ ├── iam.tf │ ├── nessus_elb.tf │ ├── opsuaa.tf │ ├── outputs.tf │ ├── read_only_access_restrictions.tf │ ├── sg_elb_uaa.tf │ ├── sg_nessus.tf │ ├── stack.tf │ ├── variables.tf │ └── versions.tf │ ├── tooling │ ├── buckets.tf │ ├── cvd_mirror.tf │ ├── elb_uaa.tf │ ├── iam.tf │ ├── nessus_elb.tf │ ├── opsuaa.tf │ ├── outputs.tf │ ├── read_only_access_restrictions.tf │ ├── s3-logs.tf │ ├── sg_elb_uaa.tf │ ├── sg_nessus.tf │ ├── stack.tf │ ├── variables.tf │ └── versions.tf │ └── westa-hub │ ├── README.md │ ├── buckets.tf │ ├── cvd_mirror.tf │ ├── elb_uaa.tf │ ├── iam.tf │ ├── key_pair.tf │ ├── nessus_elb.tf │ ├── opsuaa.tf │ ├── outputs.tf │ ├── passwords.tf │ ├── read_only_access_restrictions.tf │ ├── s3-logs.tf │ ├── sg_elb_uaa.tf │ ├── sg_nessus.tf │ ├── stack.tf │ ├── variables.tf │ └── versions.tf ├── validate.sh └── validating_locally.md /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Changes proposed in this pull request: 2 | - 3 | - 4 | - 5 | 6 | ## security considerations 7 | [Note the any security considerations here, or make note of why there are none] 8 | -------------------------------------------------------------------------------- /.github/workflows/security-considerations.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Security Considerations 3 | on: 4 | pull_request: 5 | types: [opened, edited, reopened] 6 | branches: [main, master, develop] 7 | jobs: 8 | security-considerations: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: cloud-gov/security-considerations-action@main 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Configurations 2 | environment.sh 3 | env.sh 4 | credentials.yml 5 | state.yml 6 | 7 | tmp/ 8 | tmp/* 9 | 10 | # Terraform files 11 | *.tfstate 12 | *.tfstate.backup 13 | .terraform* 14 | *.tfvars 15 | .terraform.lock.hcl 16 | *.tfplan 17 | terraform-plan-output.txt 18 | terraform.json 19 | 20 | # Eclipse IDE files 21 | .project 22 | 23 | *-state.json 24 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | repos: 3 | - repo: https://github.com/pre-commit/pre-commit-hooks 4 | rev: v2.3.0 5 | hooks: 6 | - id: end-of-file-fixer 7 | - id: trailing-whitespace 8 | - repo: https://github.com/google/yamlfmt 9 | rev: v0.13.0 10 | hooks: 11 | - id: yamlfmt 12 | - repo: https://github.com/koalaman/shellcheck-precommit 13 | rev: v0.7.2 14 | hooks: 15 | - id: shellcheck 16 | - repo: https://github.com/AleksaC/terraform-py 17 | rev: v1.9.2 18 | hooks: 19 | - id: tf-fmt 20 | types: [terraform] 21 | -------------------------------------------------------------------------------- /.yamlfmt: -------------------------------------------------------------------------------- 1 | --- 2 | formatter: 3 | type: basic 4 | include_document_start: true 5 | retain_line_breaks_single: true 6 | drop_merge_tag: true 7 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @cloud-gov/platform-ops 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Public domain 2 | 3 | This project is in the public domain within the United States, and 4 | copyright and related rights in the work worldwide are waived through 5 | the [CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/). 6 | 7 | All contributions to this project will be released under the CC0 8 | dedication. By submitting a pull request, you are agreeing to comply 9 | with this waiver of copyright interest. 10 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | **Reporting Security Issues** 3 | 4 | Please refrain from reporting security vulnerabilities through public GitHub issues. 5 | 6 | Instead, kindly report them via the information provided in [cloud.gov's security.txt](https://cloud.gov/.well-known/security.txt). 7 | 8 | When reporting, include the following details (as much as possible) to help us understand the nature and extent of the potential issue: 9 | 10 | - Type of issue (e.g., buffer overflow, SQL injection, cross-site scripting, etc.) 11 | - Full paths of related source file(s) 12 | - Location of affected source code (tag/branch/commit or direct URL) 13 | - Any special configuration required to reproduce the issue 14 | - Step-by-step instructions to reproduce the issue 15 | - Proof-of-concept or exploit code (if available) 16 | - Impact of the issue, including potential exploitation by attackers 17 | 18 | Providing this information will facilitate a quicker triage of your report. 19 | -------------------------------------------------------------------------------- /bosh/opsfiles/basic-auth.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - type: replace 3 | path: /instance_groups/name=concourse/jobs/name=atc/properties/no_really_i_dont_want_any_auth? 4 | value: false 5 | 6 | - type: replace 7 | path: /instance_groups/name=concourse/jobs/name=atc/properties/basic_auth_username? 8 | value: bootstrap 9 | 10 | - type: replace 11 | path: /instance_groups/name=concourse/jobs/name=atc/properties/basic_auth_password? 12 | value: ((basic-auth-password)) 13 | 14 | - type: replace 15 | path: /variables/- 16 | value: 17 | name: basic-auth-password 18 | type: password 19 | -------------------------------------------------------------------------------- /bosh/opsfiles/bootstrap-instance-size.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - type: replace 3 | path: /resource_pools/name=vms/cloud_properties/instance_type? 4 | value: c3.4xlarge 5 | 6 | # add disk space 7 | - type: replace 8 | path: /resource_pools/name=vms/cloud_properties/ephemeral_disk/size? 9 | value: 100_000 10 | -------------------------------------------------------------------------------- /bosh/opsfiles/iam-instance-profile.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - type: replace 3 | path: /resource_pools/name=vms/cloud_properties/iam_instance_profile? 4 | value: bootstrap 5 | -------------------------------------------------------------------------------- /bosh/opsfiles/self-signed-tls.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - type: replace 3 | path: /instance_groups/name=concourse/jobs/name=atc/properties/tls_cert? 4 | value: ((bootstrap-concourse-cert.certificate)) 5 | 6 | - type: replace 7 | path: /instance_groups/name=concourse/jobs/name=atc/properties/tls_key? 8 | value: ((bootstrap-concourse-cert.private_key)) 9 | 10 | - type: replace 11 | path: /variables/- 12 | value: 13 | name: bootstrap-ca 14 | type: certificate 15 | options: 16 | is_ca: true 17 | common_name: bootstrap-ca 18 | 19 | - type: replace 20 | path: /variables/- 21 | value: 22 | name: bootstrap-concourse-cert 23 | type: certificate 24 | options: 25 | ca: bootstrap-ca 26 | common_name: bootstrap-concourse-cert 27 | alternative_names: [((public_ip))] 28 | 29 | - type: replace 30 | path: /instance_groups/name=concourse/jobs/name=atc/properties/external_url 31 | value: https://((public_ip)):4443 32 | -------------------------------------------------------------------------------- /bosh/opsfiles/ssh-tunnel.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - type: replace 3 | path: /cloud_provider/ssh_tunnel/host 4 | value: ((public_ip)) 5 | -------------------------------------------------------------------------------- /bosh/opsfiles/vip-network.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - type: replace 3 | path: /networks/- 4 | value: 5 | name: public 6 | type: vip 7 | 8 | - type: replace 9 | path: /instance_groups/name=concourse/networks/- 10 | value: 11 | name: public 12 | static_ips: [((public_ip))] 13 | -------------------------------------------------------------------------------- /bosh/varsfiles/collect-aws-variables.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Map values from AWS key pair output 3 | private_key: ((KeyMaterial)) 4 | 5 | # Map values from terraform output 6 | default_security_groups: 7 | - ((security_group_id.value)) 8 | subnet_id: ((public_subnet_id.value)) 9 | internal_ip: ((private_ip.value)) 10 | public_ip: ((public_ip.value)) 11 | internal_cidr: ((public_subnet_cidr.value)) 12 | internal_gw: ((public_subnet_gateway.value)) 13 | -------------------------------------------------------------------------------- /bosh/varsfiles/deploy-bosh.yml: -------------------------------------------------------------------------------- 1 | --- 2 | bosh-config-git-url: https://github.com/18F/cg-deploy-bosh.git 3 | bosh-config-git-branch: master 4 | 5 | pipeline-tasks-git-url: https://github.com/18F/cg-pipeline-tasks.git 6 | pipeline-tasks-git-branch: master 7 | 8 | tf-state-file-tooling: tooling/state.yml 9 | tf-state-file-development: development/state.yml 10 | tf-state-file-staging: staging/state.yml 11 | tf-state-file-production: production/state.yml 12 | -------------------------------------------------------------------------------- /bosh/varsfiles/secret-rotation.yml: -------------------------------------------------------------------------------- 1 | --- 2 | variables: 3 | - name: common-secrets-passphrase 4 | type: password 5 | - name: master-secrets-passphrase 6 | type: password 7 | - name: tooling-secrets-passphrase 8 | type: password 9 | -------------------------------------------------------------------------------- /ci/check-certificates.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | AWS_ACCESS_KEY_ID=$(spruce json terraform-yaml-tooling/state.yml | jq -r ".terraform_outputs.iam_cert_provision_access_key_id_curr") 6 | AWS_SECRET_ACCESS_KEY=$(spruce json terraform-yaml-tooling/state.yml | jq -r ".terraform_outputs.iam_cert_provision_secret_access_key_curr") 7 | export AWS_ACCESS_KEY_ID 8 | export AWS_SECRET_ACCESS_KEY 9 | 10 | if [[ -n "${ASSUME_ROLE_ARN}" ]]; then 11 | read -r access_key_id secret_access_key session_token < <(aws sts assume-role --role-arn="${ASSUME_ROLE_ARN}" --role-session-name=concourse_cert_upload | jq -r '.Credentials.AccessKeyId, .Credentials.SecretAccessKey, .Credentials.SessionToken') 12 | export AWS_ACCESS_KEY_ID="${access_key_id}" 13 | export AWS_SECRET_ACCESS_KEY="${secret_access_key}" 14 | export AWS_SESSION_TOKEN="${session_token}" 15 | fi 16 | 17 | aws iam list-server-certificates \ 18 | --path-prefix "${CERT_PATH}" \ 19 | --no-paginate \ 20 | > certificates/metadata 21 | -------------------------------------------------------------------------------- /ci/check-certificates.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | 4 | inputs: 5 | - name: cg-provision-repo 6 | - name: terraform-yaml-tooling 7 | 8 | outputs: 9 | - name: certificates 10 | 11 | run: 12 | path: cg-provision-repo/ci/check-certificates.sh 13 | 14 | params: 15 | AWS_DEFAULT_REGION: 16 | CERT_PATH: 17 | ASSUME_ROLE_ARN: 18 | -------------------------------------------------------------------------------- /ci/concourse-defaults.yml: -------------------------------------------------------------------------------- 1 | --- 2 | cg_provision_git_url: https://github.com/18F/cg-provision.git 3 | cg_provision_git_repo: 18F/cg-provision 4 | cg_provision_git_branch: master 5 | 6 | cg_provision_development_git_url: https://github.com/18F/cg-provision 7 | cg_provision_development_git_branch: master 8 | 9 | pipeline_tasks_git_url: https://github.com/18F/cg-pipeline-tasks.git 10 | pipeline_tasks_git_branch: master 11 | 12 | aws_default_region: us-gov-west-1 13 | 14 | aws_s3_tfstate_bucket: terraform-state 15 | aws_s3_cloudtrail_bucket: cg-s3-cloudtrail 16 | 17 | tf_state_file_tooling: tooling/state.yml 18 | tf_state_file_development: development/state.yml 19 | tf_state_file_staging: staging/state.yml 20 | tf_state_file_production: production/state.yml 21 | 22 | aws_external_region: us-east-1 23 | aws_external_s3_tfstate_bucket: cg-terraform-state 24 | 25 | tf_state_file_external_staging: external-staging/state.yml 26 | tf_state_file_external_production: external-production/state.yml 27 | 28 | slack-channel: "#cg-platform" 29 | slack-username: concourse 30 | slack-icon-url: http://cl.ly/image/3e1h0H3H2s0P/concourse-logo.png 31 | -------------------------------------------------------------------------------- /ci/delete-old-certificates.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # upload a certificate to the tooling account 3 | platform: linux 4 | 5 | inputs: 6 | - name: cg-provision-repo 7 | - name: terraform-yaml-tooling 8 | - name: certificates 9 | - name: acme 10 | 11 | run: 12 | path: cg-provision-repo/ci/delete-old-certificates.sh 13 | 14 | params: 15 | AWS_DEFAULT_REGION: 16 | CERT_PATH: 17 | CERT_PREFIX: 18 | ASSUME_ROLE_ARN: 19 | -------------------------------------------------------------------------------- /ci/provision-certificate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | 4 | inputs: 5 | - name: cg-provision-repo 6 | - name: terraform-yaml-external 7 | - name: certificates 8 | 9 | outputs: 10 | - name: acme 11 | 12 | run: 13 | path: cg-provision-repo/ci/provision-certificate.sh 14 | 15 | params: 16 | CERT_PREFIX: 17 | ACME_SERVER: 18 | DOMAIN: 19 | EMAIL: cloud-gov-operations@gsa.gov 20 | -------------------------------------------------------------------------------- /ci/scripts/terraform_fmt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | which terraform > /dev/null 2>&1 || { 5 | echo "Aborted. Please install terraform by following https://www.terraform.io/intro/getting-started/install.html" 1>&2 6 | exit 1 7 | } 8 | 9 | echo "Any files that follow were not formatted with terraform fmt:" 10 | terraform fmt -recursive -diff -check 11 | -------------------------------------------------------------------------------- /ci/scripts/update-db.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | SCRIPTPATH=$( cd "$(dirname "$0")" ; pwd -P ) 4 | 5 | # Check environment variables 6 | export DATABASES="${DATABASES}" 7 | export EXTENSIONS="${CUSTOM_EXTENSIONS:-citext uuid-ossp pgcrypto pg_stat_statements}" 8 | export STATE_FILE_PATH="${STATE_FILE_PATH}" 9 | export TERRAFORM="${TERRAFORM_BIN:-terraform}" 10 | export TERRAFORM_DB_HOST_FIELD="${TERRAFORM_DB_HOST_FIELD}" 11 | export TERRAFORM_DB_USERNAME_FIELD="${TERRAFORM_DB_USERNAME_FIELD}" 12 | export TERRAFORM_DB_PASSWORD_FIELD="${TERRAFORM_DB_PASSWORD_FIELD}" 13 | 14 | "$SCRIPTPATH"/create-and-update-db.sh 15 | -------------------------------------------------------------------------------- /ci/upload-certificate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # upload a certificate to the tooling account 3 | platform: linux 4 | 5 | inputs: 6 | - name: cg-provision-repo 7 | - name: terraform-yaml-tooling 8 | - name: certificates 9 | - name: acme 10 | 11 | run: 12 | path: cg-provision-repo/ci/upload-certificate.sh 13 | 14 | params: 15 | AWS_DEFAULT_REGION: 16 | CERT_PATH: 17 | CERT_PREFIX: 18 | ASSUME_ROLE_ARN: 19 | -------------------------------------------------------------------------------- /ci/waf-tests/requirements.txt: -------------------------------------------------------------------------------- 1 | attrs==21.4.0 2 | certifi==2024.7.4 3 | charset-normalizer==2.0.12 4 | idna==3.7 5 | iniconfig==1.1.1 6 | packaging==21.3 7 | pluggy==1.0.0 8 | py==1.11.0 9 | pyparsing==3.0.7 10 | pytest==7.0.1 11 | requests==2.32.2 12 | tomli==2.0.1 13 | urllib3==1.26.19 14 | -------------------------------------------------------------------------------- /ci/waf-tests/test-waf-rules.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | python3 -m venv venv 6 | # this file doesn't exist for shellcheck to check, but we know it will exist later 7 | # shellcheck disable=SC1091 8 | source venv/bin/activate 9 | 10 | cd ./cg-provision-repo/ci/waf-tests/ 11 | 12 | python3 -m pip install -r requirements.txt 13 | 14 | pytest -v 15 | -------------------------------------------------------------------------------- /ci/waf-tests/test-waf-rules.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | 4 | inputs: 5 | - name: cg-provision-repo 6 | - name: waf-test-files 7 | 8 | run: 9 | path: cg-provision-repo/ci/waf-tests/test-waf-rules.sh 10 | 11 | params: 12 | WAF_TEST_APP_URL: 13 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Further docs on Cloud.gov provisioning system 2 | -------------------------------------------------------------------------------- /env.example.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export WORKSPACE_DIR=./tmp 3 | export AWS_ACCESS_KEY_ID= 4 | export AWS_SECRET_ACCESS_KEY= 5 | export AWS_DEFAULT_REGION=us-gov-west-1 6 | 7 | # Choose between these two, depending on what you are bootstrapping. 8 | #export TERRAFORM_PIPELINE_FILE=ci/pipeline-development.yml 9 | export TERRAFORM_PIPELINE_FILE=ci/pipeline.yml 10 | 11 | # Uncomment these after you've generated the TERRAFORM_PROVISION_CREDENTIALS_FILE 12 | # and before step 03 13 | #export TERRAFORM_PROVISION_CREDENTIALS_FILE="${WORKSPACE_DIR}"/cg-provision.yml 14 | #export TF_STATE_BUCKET=$(bosh interpolate ${TERRAFORM_PROVISION_CREDENTIALS_FILE} --path /aws_s3_tfstate_bucket) 15 | 16 | export VARZ_BUCKET=cloud-gov-varz 17 | export SEMVER_BUCKET=cg-semver 18 | export BOSH_RELEASES_BUCKET=cloud-gov-bosh-releases 19 | export BOSH_RELEASES_BLOBSTORE_BUCKET=cloud-gov-release-blobstore 20 | export TOOLING_SECRETS_PASSPHRASE="XXX" 21 | export CONCOURSE_SECRETS_PASSPHRASE="XXX" 22 | export SLACK_WEBHOOK_URL="XXX" 23 | export NESSUS_KEY="XXX" 24 | export NESSUS_SERVER="XXX" 25 | export TRIPWIRE_LOCALPASS="XXX" 26 | export TRIPWIRE_SITEPASS="XXX" 27 | -------------------------------------------------------------------------------- /scripts/add_environment/env.example.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export WORKSPACE_DIR=./tmp 3 | export AWS_ACCESS_KEY_ID= 4 | export AWS_SECRET_ACCESS_KEY= 5 | export AWS_DEFAULT_REGION= 6 | # this should be the concourse iaas worker role in the tooling aws account 7 | export TF_VAR_tf_remote_role_arn= 8 | export TF_VAR_cert_remote_role_arn= 9 | export TV_VAR_environment_name= 10 | -------------------------------------------------------------------------------- /scripts/add_environment/manage_environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eux 4 | 5 | if [[ -z "${TF_VAR_cert_remote_role_arn}" ]]; then 6 | echo "you must set TF_VAR_remote_role_arn" 7 | echo "check the README for more info" 8 | exit 1 9 | fi 10 | 11 | mkdir -p "${WORKSPACE_DIR}" 12 | TF="terraform -chdir=./terraform/stacks/managedaccount" 13 | # Provision terraform infrastructure 14 | ${TF} init 15 | ${TF} validate 16 | ${TF} apply 17 | ${TF} output -json > "${WORKSPACE_DIR}"/terraform-outputs.json 18 | -------------------------------------------------------------------------------- /scripts/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | if [ "X$1" = "Xapply" ] || [ "X$1" = "Xdestroy" ] || [ "X$1" = "Xplan" ]; then 5 | 6 | OPTIONS="-refresh" 7 | if [ "X$1" = "Xdestroy" ]; then 8 | OPTIONS="-force" 9 | fi 10 | 11 | SCRIPT_DIR="$(dirname "$0")" 12 | # shellcheck disable=SC1091 13 | . "${SCRIPT_DIR}"/environment.sh 14 | STACK_NAME="bootstrap" 15 | 16 | terraform get \ 17 | -update \ 18 | "${SCRIPT_DIR}"/../terraform/stacks/"${STACK_NAME}" 19 | 20 | terraform "$1" \ 21 | "${OPTIONS}" \ 22 | "${SCRIPT_DIR}"/../terraform/stacks/"${STACK_NAME}" 23 | 24 | else 25 | echo "Must specify either 'plan', 'apply' or 'destroy'" 26 | exit 1 27 | fi 28 | -------------------------------------------------------------------------------- /scripts/bootstrap/01-bootstrap-terraform.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eux 4 | 5 | # Create AWS keypair 6 | if [ ! -f "${WORKSPACE_DIR}"/aws-keypair.json ]; then 7 | aws ec2 delete-key-pair --key-name bootstrap 8 | aws ec2 create-key-pair --key-name bootstrap > "${WORKSPACE_DIR}"/aws-keypair.json 9 | fi 10 | 11 | # Provision terraform infrastructure 12 | terraform init ./terraform/stacks/bootstrap 13 | terraform apply ./terraform/stacks/bootstrap 14 | terraform output -json > "${WORKSPACE_DIR}"/terraform-outputs.json 15 | -------------------------------------------------------------------------------- /scripts/bootstrap/04-bootstrap-terraform-peering.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eux 4 | 5 | # Now that tooling stack exists, reapply bootstrap stack to create peering connection 6 | # between bootstrap and tooling 7 | export TF_VAR_use_vpc_peering="1" 8 | export TF_VAR_tooling_state_bucket="${TF_STATE_BUCKET}" 9 | 10 | terraform apply ./terraform/stacks/bootstrap 11 | -------------------------------------------------------------------------------- /scripts/bootstrap/07-deploy-concourse.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eux 4 | 5 | # Set deploy-concourse pipeline 6 | fly --target bootstrap set-pipeline \ 7 | --pipeline deploy-concourse \ 8 | --config ../cg-deploy-concourse/ci/pipeline-development.yml \ 9 | --load-vars-from "${WORKSPACE_DIR}"/concourse-environment.yml \ 10 | --load-vars-from ../cg-deploy-concourse/ci/concourse-defaults.yml \ 11 | --var secrets-bucket="${VARZ_BUCKET}" \ 12 | --var concourse-production-deployment-bosh-target="$(bosh interpolate "${WORKSPACE_DIR}"/tooling-state.yml --path /terraform_outputs/tooling_bosh_static_ip)" \ 13 | --var concourse-production-private-passphrase="${CONCOURSE_SECRETS_PASSPHRASE}" \ 14 | --var tf-state-bucket="${TF_STATE_BUCKET}" \ 15 | --var slack-webhook-url="${SLACK_WEBHOOK_URL}" 16 | fly --target bootstrap unpause-pipeline --pipeline deploy-concourse 17 | 18 | # Deploy concourse 19 | fly --target bootstrap trigger-job --job deploy-concourse/deploy-concourse-production --watch 20 | -------------------------------------------------------------------------------- /scripts/bootstrap/setup-bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eux 4 | 5 | # Clone necessary git repositories 6 | git clone https://github.com/concourse/concourse-deployment 7 | git clone https://github.com/cloud-gov/cg-deploy-bosh 8 | git clone https://github.com/cloud-gov/cg-deploy-concourse 9 | git clone https://github.com/cloud-gov/cg-pipeline-tasks 10 | git clone https://github.com/cloud-gov/cg-scripts 11 | git clone https://github.com/cloud-gov/cg-secret-rotation 12 | -------------------------------------------------------------------------------- /scripts/bootstrap/teardown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eux 4 | 5 | az=$(aws ec2 describe-availability-zones | jq -r '.AvailabilityZones[0].ZoneName') 6 | 7 | # Delete bootstrap concourse 8 | bosh delete-env ../concourse-deployment/lite/concourse.yml \ 9 | --state "${WORKSPACE_DIR}"/bootstrap-concourse-state.json \ 10 | --vars-store "${WORKSPACE_DIR}"/bootstrap-concourse-creds.yml \ 11 | -o ../concourse-deployment/lite/infrastructures/aws.yml \ 12 | -o ./bosh/opsfiles/basic-auth.yml \ 13 | -o ./bosh/opsfiles/self-signed-tls.yml \ 14 | -l ../concourse-deployment/versions.yml \ 15 | -o ./bosh/opsfiles/ssh-tunnel.yml \ 16 | -o ./bosh/opsfiles/vip-network.yml \ 17 | -l "${WORKSPACE_DIR}"/aws-variables.yml \ 18 | -v region="${AWS_DEFAULT_REGION}" \ 19 | -v default_key_name=bootstrap \ 20 | -v az="${az}" \ 21 | -v access_key_id="${AWS_ACCESS_KEY_ID}" \ 22 | -v secret_access_key="${AWS_SECRET_ACCESS_KEY}" 23 | 24 | # Delete AWS keypair 25 | aws ec2 delete-key-pair --key-name bootstrap 26 | 27 | # Terraform 28 | terraform destroy ./terraform/stacks/bootstrap 29 | -------------------------------------------------------------------------------- /scripts/run-plan.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Run the plan to test any changes to the infrastructure 5 | # 6 | # environment.sh doesn't exist when shellcheck runs, but will when the script runs 7 | # shellcheck disable=SC1091 8 | . "$(dirname "$0")"/environment.sh 9 | 10 | for STACK_NAME in tooling production staging 11 | do 12 | #STACK_NAME="tooling" 13 | rm -rf .terraform 14 | # trust that TF_VAR_remote_state_bucket will exist 15 | # shellcheck disable=SC2154 16 | terraform remote config \ 17 | -backend=s3 \ 18 | -backend-config="bucket=${TF_VAR_remote_state_bucket}" \ 19 | -backend-config="key=${STACK_NAME}/terraform.tfstate" 20 | 21 | terraform get \ 22 | -update \ 23 | ./terraform/stacks/"${STACK_NAME}" 24 | 25 | terraform plan \ 26 | -refresh=true \ 27 | -var-file="${STACK_NAME}".tfvars \ 28 | ./terraform/stacks/"${STACK_NAME}" 29 | done 30 | -------------------------------------------------------------------------------- /scripts/update-dependabot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # delete the exising configuration since it will be overridden 4 | yq -i 'del(.updates)' ".github/dependabot.yml" 5 | 6 | for DIR in $(find . -name '*.tf' -not -path '*.terraform*' -exec dirname {} \; | sort -u); do 7 | dir=${DIR:1} \ 8 | yq -i '."updates"+=[{"package-ecosystem":"terraform" | . style="double","directory":env(dir) | . style="double","schedule":{"interval":"weekly" | . style="double"}}]' \ 9 | .github/dependabot.yml 10 | done 11 | -------------------------------------------------------------------------------- /terraform/modules/autoscaler/outputs.tf: -------------------------------------------------------------------------------- 1 | 2 | output "cf_as_rds_url" { 3 | value = module.cf_as_database.rds_url 4 | } 5 | 6 | output "cf_as_rds_host" { 7 | value = module.cf_as_database.rds_host 8 | } 9 | 10 | output "cf_as_rds_port" { 11 | value = module.cf_as_database.rds_port 12 | } 13 | 14 | output "cf_as_rds_username" { 15 | value = module.cf_as_database.rds_username 16 | } 17 | 18 | output "cf_as_rds_password" { 19 | value = module.cf_as_database.rds_password 20 | sensitive = true 21 | } 22 | 23 | output "cf_as_rds_engine" { 24 | value = module.cf_as_database.rds_engine 25 | } 26 | -------------------------------------------------------------------------------- /terraform/modules/autoscaler/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/bosh_vpc/ec2.tf: -------------------------------------------------------------------------------- 1 | resource "aws_key_pair" "bosh" { 2 | key_name = "${var.stack_description}-key" 3 | public_key = var.bosh_default_ssh_public_key 4 | } 5 | -------------------------------------------------------------------------------- /terraform/modules/bosh_vpc/sg_local_vpc_traffic.tf: -------------------------------------------------------------------------------- 1 | /* 2 | * Variables required: 3 | * stack_description 4 | * 5 | * Resources required: 6 | * aws_vpc referenced as 'main_vpc' 7 | */ 8 | 9 | resource "aws_security_group" "local_vpc_traffic" { 10 | description = "Enable access to all VPC CIDR block ips" 11 | vpc_id = aws_vpc.main_vpc.id 12 | 13 | ingress { 14 | from_port = 0 15 | to_port = 0 16 | protocol = "-1" 17 | cidr_blocks = [aws_vpc.main_vpc.cidr_block] 18 | } 19 | 20 | egress { 21 | from_port = 0 22 | to_port = 0 23 | protocol = "-1" 24 | cidr_blocks = ["0.0.0.0/0"] 25 | } 26 | 27 | tags = { 28 | Name = "${var.stack_description} - Local Traffic ${aws_vpc.main_vpc.cidr_block}" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /terraform/modules/bosh_vpc/sg_web_traffic.tf: -------------------------------------------------------------------------------- 1 | /* 2 | * Variables required: 3 | * stack_description 4 | * 5 | * Resources required: 6 | * aws_vpc referenced as 'main_vpc' 7 | */ 8 | 9 | resource "aws_security_group" "web_traffic" { 10 | description = "Allow access to incoming web type traffic" 11 | vpc_id = aws_vpc.main_vpc.id 12 | 13 | ingress { 14 | from_port = 80 15 | to_port = 80 16 | protocol = "tcp" 17 | cidr_blocks = ["0.0.0.0/0"] 18 | ipv6_cidr_blocks = ["::/0"] 19 | } 20 | 21 | ingress { 22 | from_port = 443 23 | to_port = 443 24 | protocol = "tcp" 25 | cidr_blocks = ["0.0.0.0/0"] 26 | ipv6_cidr_blocks = ["::/0"] 27 | } 28 | 29 | egress { 30 | from_port = 0 31 | to_port = 0 32 | protocol = "-1" 33 | cidr_blocks = ["0.0.0.0/0"] 34 | ipv6_cidr_blocks = ["::/0"] 35 | } 36 | 37 | tags = { 38 | Name = "${var.stack_description} - Incoming Web Traffic" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /terraform/modules/bosh_vpc/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/bosh_vpc_v2/ec2.tf: -------------------------------------------------------------------------------- 1 | resource "aws_key_pair" "bosh" { 2 | key_name = "${var.stack_description}-key" 3 | public_key = var.bosh_default_ssh_public_key 4 | } 5 | -------------------------------------------------------------------------------- /terraform/modules/bosh_vpc_v2/sg_local_vpc_traffic.tf: -------------------------------------------------------------------------------- 1 | /* 2 | * Variables required: 3 | * stack_description 4 | * 5 | * Resources required: 6 | * aws_vpc referenced as 'main_vpc' 7 | */ 8 | 9 | resource "aws_security_group" "local_vpc_traffic" { 10 | description = "Enable access to all VPC CIDR block ips" 11 | vpc_id = aws_vpc.main_vpc.id 12 | 13 | ingress { 14 | from_port = 0 15 | to_port = 0 16 | protocol = "-1" 17 | cidr_blocks = [aws_vpc.main_vpc.cidr_block] 18 | } 19 | 20 | egress { 21 | from_port = 0 22 | to_port = 0 23 | protocol = "-1" 24 | cidr_blocks = ["0.0.0.0/0"] 25 | } 26 | 27 | tags = { 28 | Name = "${var.stack_description} - Local Traffic ${aws_vpc.main_vpc.cidr_block}" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /terraform/modules/bosh_vpc_v2/sg_restricted_web_traffic.tf: -------------------------------------------------------------------------------- 1 | /* 2 | * Variables required: 3 | * stack_description 4 | * 5 | * Resources required: 6 | * aws_vpc referenced as 'main_vpc' 7 | */ 8 | 9 | resource "aws_security_group" "restricted_web_traffic" { 10 | description = "Restricted web type traffic" 11 | vpc_id = aws_vpc.main_vpc.id 12 | 13 | ingress { 14 | from_port = 80 15 | to_port = 80 16 | protocol = "tcp" 17 | cidr_blocks = var.restricted_ingress_web_cidrs 18 | ipv6_cidr_blocks = var.restricted_ingress_web_ipv6_cidrs 19 | } 20 | 21 | ingress { 22 | from_port = 443 23 | to_port = 443 24 | protocol = "tcp" 25 | cidr_blocks = var.restricted_ingress_web_cidrs 26 | ipv6_cidr_blocks = var.restricted_ingress_web_ipv6_cidrs 27 | } 28 | 29 | egress { 30 | from_port = 0 31 | to_port = 0 32 | protocol = "-1" 33 | cidr_blocks = ["0.0.0.0/0"] 34 | ipv6_cidr_blocks = ["::/0"] 35 | } 36 | 37 | tags = { 38 | Name = "${var.stack_description} - Restricted Incoming Web Traffic" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /terraform/modules/bosh_vpc_v2/sg_web_traffic.tf: -------------------------------------------------------------------------------- 1 | /* 2 | * Variables required: 3 | * stack_description 4 | * 5 | * Resources required: 6 | * aws_vpc referenced as 'main_vpc' 7 | */ 8 | 9 | resource "aws_security_group" "web_traffic" { 10 | description = "Allow access to incoming web type traffic" 11 | vpc_id = aws_vpc.main_vpc.id 12 | 13 | ingress { 14 | from_port = 80 15 | to_port = 80 16 | protocol = "tcp" 17 | cidr_blocks = ["0.0.0.0/0"] 18 | ipv6_cidr_blocks = ["::/0"] 19 | } 20 | 21 | ingress { 22 | from_port = 443 23 | to_port = 443 24 | protocol = "tcp" 25 | cidr_blocks = ["0.0.0.0/0"] 26 | ipv6_cidr_blocks = ["::/0"] 27 | } 28 | 29 | egress { 30 | from_port = 0 31 | to_port = 0 32 | protocol = "-1" 33 | cidr_blocks = ["0.0.0.0/0"] 34 | ipv6_cidr_blocks = ["::/0"] 35 | } 36 | 37 | tags = { 38 | Name = "${var.stack_description} - Incoming Web Traffic" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /terraform/modules/bosh_vpc_v2/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/cdn_broker/outputs.tf: -------------------------------------------------------------------------------- 1 | output "username" { 2 | value = var.username 3 | } 4 | 5 | output "access_key_id_prev" { 6 | value = "" 7 | } 8 | 9 | output "secret_access_key_prev" { 10 | value = "" 11 | } 12 | 13 | output "access_key_id_curr" { 14 | value = aws_iam_access_key.iam_access_key_v4.id 15 | } 16 | 17 | output "secret_access_key_curr" { 18 | value = aws_iam_access_key.iam_access_key_v4.secret 19 | } 20 | -------------------------------------------------------------------------------- /terraform/modules/cdn_broker/variables.tf: -------------------------------------------------------------------------------- 1 | variable "username" { 2 | } 3 | 4 | variable "account_id" { 5 | } 6 | 7 | variable "aws_partition" { 8 | } 9 | 10 | variable "bucket" { 11 | } 12 | 13 | variable "cloudfront_prefix" { 14 | } 15 | 16 | variable "hosted_zone" { 17 | } 18 | -------------------------------------------------------------------------------- /terraform/modules/cdn_broker/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/cloudfoundry/elb_waf.tf: -------------------------------------------------------------------------------- 1 | resource "aws_wafv2_regex_pattern_set" "jndi_regex" { 2 | name = "${var.stack_description}-waf-jndi-regex" 3 | description = "Regex Pattern Set for JNDI" 4 | scope = "REGIONAL" 5 | 6 | dynamic "regular_expression" { 7 | for_each = var.waf_regular_expressions 8 | content { 9 | regex_string = regular_expression.value 10 | } 11 | } 12 | } 13 | 14 | resource "aws_wafv2_regex_pattern_set" "drop_logs_regex" { 15 | name = "${var.stack_description}-waf-drop-logs-regex" 16 | description = "Regex Pattern Set Drop Logs Hosts" 17 | scope = "REGIONAL" 18 | 19 | dynamic "regular_expression" { 20 | for_each = var.waf_drop_logs_hosts_regular_expressions 21 | content { 22 | regex_string = regular_expression.value 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /terraform/modules/cloudfoundry/service_subnets.tf: -------------------------------------------------------------------------------- 1 | /* 2 | * Variables required: 3 | * stack_description 4 | * az1 5 | * az2 6 | * services_cidr_1 7 | * services_cidr_2 8 | * vpc_id 9 | * private_route_table_az1 10 | * private_route_table_az2 11 | * 12 | */ 13 | 14 | resource "aws_subnet" "az1_services" { 15 | vpc_id = var.vpc_id 16 | cidr_block = var.services_cidr_1 17 | availability_zone = var.az1 18 | 19 | tags = { 20 | Name = "${var.stack_description} (Services AZ1)" 21 | } 22 | } 23 | 24 | resource "aws_subnet" "az2_services" { 25 | vpc_id = var.vpc_id 26 | cidr_block = var.services_cidr_2 27 | availability_zone = var.az2 28 | 29 | tags = { 30 | Name = "${var.stack_description} (Services AZ2)" 31 | } 32 | } 33 | 34 | resource "aws_route_table_association" "az1_services_rta" { 35 | subnet_id = aws_subnet.az1_services.id 36 | route_table_id = var.private_route_table_az1 37 | } 38 | 39 | resource "aws_route_table_association" "az2_services_rta" { 40 | subnet_id = aws_subnet.az2_services.id 41 | route_table_id = var.private_route_table_az2 42 | } 43 | -------------------------------------------------------------------------------- /terraform/modules/cloudfoundry/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/cloudfront/variables.tf: -------------------------------------------------------------------------------- 1 | variable "origin" { 2 | type = object({ 3 | lb_dns_name = string 4 | lb_http_port = number 5 | lb_https_port = number 6 | }) 7 | } 8 | 9 | # variable "iam_certificate_id" { 10 | # type = string 11 | # } 12 | 13 | variable "aliases" { 14 | type = set(string) 15 | default = [] 16 | } 17 | 18 | variable "acl_arn" { 19 | type = string 20 | } 21 | -------------------------------------------------------------------------------- /terraform/modules/cloudfront/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/cloudwatch/policies.tf: -------------------------------------------------------------------------------- 1 | # Allow managed OpenSearch clusters, which we broker to customers, to publish logs 2 | # to CloudWatch. Necessary to enable logging on those clusters. 3 | data "aws_iam_policy_document" "elasticsearch-log-publishing-policy" { 4 | statement { 5 | actions = [ 6 | "logs:CreateLogStream", 7 | "logs:PutLogEvents", 8 | ] 9 | 10 | resources = ["arn:${var.aws_partition}:logs:*"] 11 | 12 | principals { 13 | identifiers = ["es.amazonaws.com"] 14 | type = "Service" 15 | } 16 | } 17 | } 18 | 19 | resource "aws_cloudwatch_log_resource_policy" "elasticsearch-log-publishing-policy" { 20 | policy_document = data.aws_iam_policy_document.elasticsearch-log-publishing-policy.json 21 | policy_name = "elasticsearch-log-publishing-policy" 22 | } 23 | -------------------------------------------------------------------------------- /terraform/modules/cloudwatch/variables.tf: -------------------------------------------------------------------------------- 1 | variable "stack_description" { 2 | 3 | } 4 | 5 | variable "cg_platform_notifications_arn" { 6 | type = string 7 | description = "ARN for the platform-notifications SNS Topic" 8 | 9 | } 10 | 11 | variable "cg_platform_slack_notifications_arn" { 12 | type = string 13 | description = "ARN for the platform-slack-notifications SNS Topic" 14 | } 15 | 16 | variable "load_balancer_dns" { 17 | 18 | } 19 | 20 | variable "aws_partition" { 21 | 22 | } 23 | -------------------------------------------------------------------------------- /terraform/modules/cloudwatch/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/concourse/elb.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb_target_group" "concourse_target" { 2 | name = "${var.stack_description}-concourse-${var.suffix}" 3 | port = 8080 4 | protocol = "HTTP" 5 | vpc_id = var.vpc_id 6 | 7 | health_check { 8 | healthy_threshold = 2 9 | unhealthy_threshold = 10 10 | timeout = 5 11 | interval = 30 12 | matcher = 200 13 | } 14 | 15 | stickiness { 16 | type = "lb_cookie" 17 | enabled = true 18 | } 19 | } 20 | 21 | resource "aws_lb_listener_rule" "concourse_listener_rule" { 22 | count = length(var.hosts) 23 | 24 | listener_arn = var.listener_arn 25 | 26 | action { 27 | type = "forward" 28 | target_group_arn = aws_lb_target_group.concourse_target.arn 29 | } 30 | 31 | condition { 32 | host_header { 33 | values = [element(var.hosts, count.index)] 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /terraform/modules/concourse/network.tf: -------------------------------------------------------------------------------- 1 | /* 2 | * Variables required: 3 | * stack_description 4 | * concourse_az 5 | * concourse_cidr 6 | * route_table_id 7 | * vpc_id 8 | * 9 | */ 10 | 11 | resource "aws_subnet" "concourse" { 12 | vpc_id = var.vpc_id 13 | cidr_block = var.concourse_cidr 14 | availability_zone = var.concourse_az 15 | 16 | tags = { 17 | Name = "${var.stack_description} (Concourse - ${var.concourse_cidr})" 18 | } 19 | } 20 | 21 | resource "aws_route_table_association" "concourse_rta" { 22 | subnet_id = aws_subnet.concourse.id 23 | route_table_id = var.route_table_id 24 | } 25 | -------------------------------------------------------------------------------- /terraform/modules/concourse/outputs.tf: -------------------------------------------------------------------------------- 1 | output "concourse_subnet" { 2 | value = aws_subnet.concourse.id 3 | } 4 | 5 | output "concourse_subnet_cidr" { 6 | value = aws_subnet.concourse.cidr_block 7 | } 8 | 9 | output "concourse_security_group" { 10 | value = aws_security_group.concourse.id 11 | } 12 | 13 | /* RDS Concourse Instance */ 14 | output "concourse_rds_identifier" { 15 | value = module.rds_96.rds_identifier 16 | } 17 | 18 | output "concourse_rds_name" { 19 | value = module.rds_96.rds_name 20 | } 21 | 22 | output "concourse_rds_host" { 23 | value = module.rds_96.rds_host 24 | } 25 | 26 | output "concourse_rds_port" { 27 | value = module.rds_96.rds_port 28 | } 29 | 30 | output "concourse_rds_url" { 31 | value = module.rds_96.rds_url 32 | } 33 | 34 | output "concourse_rds_username" { 35 | value = module.rds_96.rds_username 36 | } 37 | 38 | output "concourse_rds_password" { 39 | value = module.rds_96.rds_password 40 | sensitive = true 41 | } 42 | 43 | output "concourse_lb_target_group" { 44 | value = aws_lb_target_group.concourse_target.name 45 | } 46 | -------------------------------------------------------------------------------- /terraform/modules/concourse/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/concourse_v2/elb.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb_target_group" "concourse_target" { 2 | name = "${var.stack_description}-concourse-target" 3 | port = 8080 4 | protocol = "HTTP" 5 | vpc_id = var.vpc_id 6 | 7 | health_check { 8 | healthy_threshold = 2 9 | unhealthy_threshold = 10 10 | timeout = 5 11 | interval = 30 12 | matcher = 200 13 | } 14 | 15 | stickiness { 16 | type = "lb_cookie" 17 | enabled = true 18 | } 19 | } 20 | 21 | resource "aws_lb_listener_rule" "concourse_listener_rule" { 22 | count = length(var.hosts) 23 | 24 | listener_arn = var.listener_arn 25 | 26 | action { 27 | type = "forward" 28 | target_group_arn = aws_lb_target_group.concourse_target.arn 29 | } 30 | 31 | condition { 32 | host_header { 33 | values = [element(var.hosts, count.index)] 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /terraform/modules/concourse_v2/network.tf: -------------------------------------------------------------------------------- 1 | /* 2 | * Variables required: 3 | * stack_description 4 | * concourse_availability_zones 5 | * concourse_cidrs 6 | * route_table_ids 7 | * vpc_id 8 | * 9 | */ 10 | 11 | resource "aws_subnet" "concourse" { 12 | count = length(var.concourse_availability_zones) 13 | 14 | vpc_id = var.vpc_id 15 | cidr_block = var.concourse_cidrs[count.index] 16 | availability_zone = var.concourse_availability_zones[count.index] 17 | 18 | tags = { 19 | Name = "${var.stack_description} (Concourse - ${var.concourse_cidrs[count.index]})" 20 | } 21 | } 22 | 23 | resource "aws_route_table_association" "concourse_rta" { 24 | count = length(var.concourse_availability_zones) 25 | 26 | subnet_id = aws_subnet.concourse[count.index].id 27 | route_table_id = var.route_table_ids[count.index] 28 | } 29 | -------------------------------------------------------------------------------- /terraform/modules/concourse_v2/outputs.tf: -------------------------------------------------------------------------------- 1 | output "concourse_subnet_ids" { 2 | value = aws_subnet.concourse[*].id 3 | } 4 | 5 | output "concourse_subnet_cidrs" { 6 | value = aws_subnet.concourse[*].cidr_block 7 | } 8 | 9 | output "concourse_security_group" { 10 | value = aws_security_group.concourse.id 11 | } 12 | 13 | /* RDS Concourse Instance */ 14 | output "concourse_rds_identifier" { 15 | value = module.rds_96.rds_identifier 16 | } 17 | 18 | output "concourse_rds_name" { 19 | value = module.rds_96.rds_name 20 | } 21 | 22 | output "concourse_rds_host" { 23 | value = module.rds_96.rds_host 24 | } 25 | 26 | output "concourse_rds_port" { 27 | value = module.rds_96.rds_port 28 | } 29 | 30 | output "concourse_rds_url" { 31 | value = module.rds_96.rds_url 32 | } 33 | 34 | output "concourse_rds_username" { 35 | value = module.rds_96.rds_username 36 | } 37 | 38 | output "concourse_rds_password" { 39 | value = module.rds_96.rds_password 40 | sensitive = true 41 | } 42 | 43 | output "concourse_lb_target_group" { 44 | value = aws_lb_target_group.concourse_target.name 45 | } 46 | -------------------------------------------------------------------------------- /terraform/modules/concourse_v2/rds.tf: -------------------------------------------------------------------------------- 1 | module "rds_96" { 2 | source = "../rds" 3 | 4 | stack_description = "concourse-${var.stack_description}" 5 | rds_db_name = var.rds_db_name 6 | rds_instance_type = var.rds_instance_type 7 | rds_db_size = var.rds_db_size 8 | rds_db_storage_type = var.rds_db_storage_type 9 | rds_db_iops = var.rds_db_iops 10 | rds_db_engine_version = var.rds_db_engine_version 11 | rds_username = var.rds_username 12 | rds_password = var.rds_password 13 | rds_subnet_group = var.rds_subnet_group 14 | rds_security_groups = var.rds_security_groups 15 | rds_parameter_group_name = var.rds_parameter_group_name 16 | rds_parameter_group_family = var.rds_parameter_group_family 17 | rds_allow_major_version_upgrade = var.rds_allow_major_version_upgrade 18 | rds_apply_immediately = var.rds_apply_immediately 19 | rds_multi_az = var.rds_multi_az 20 | rds_final_snapshot_identifier = var.rds_final_snapshot_identifier 21 | } 22 | -------------------------------------------------------------------------------- /terraform/modules/concourse_v2/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/credhub/alb.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb_target_group" "credhub_target" { 2 | name = "${var.stack_description}-credhub-${var.credhub_az1}" 3 | port = 8844 4 | protocol = "HTTPS" 5 | vpc_id = var.vpc_id 6 | 7 | health_check { 8 | healthy_threshold = 2 9 | unhealthy_threshold = 10 10 | timeout = 5 11 | interval = 30 12 | matcher = 200 13 | port = 8844 14 | path = "/health" 15 | protocol = "HTTPS" 16 | } 17 | 18 | stickiness { 19 | type = "lb_cookie" 20 | enabled = true 21 | } 22 | } 23 | 24 | resource "aws_lb_listener_rule" "credhub_listener_rule" { 25 | count = length(var.hosts) 26 | 27 | listener_arn = var.listener_arn 28 | 29 | action { 30 | type = "forward" 31 | target_group_arn = aws_lb_target_group.credhub_target.arn 32 | } 33 | 34 | condition { 35 | host_header { 36 | values = [element(var.hosts, count.index)] 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /terraform/modules/credhub/network.tf: -------------------------------------------------------------------------------- 1 | resource "aws_subnet" "credhub_az1" { 2 | vpc_id = var.vpc_id 3 | cidr_block = var.credhub_cidr_az1 4 | availability_zone = var.credhub_az1 5 | 6 | tags = { 7 | Name = "${var.stack_description} (Credhub - ${var.credhub_cidr_az1})" 8 | } 9 | } 10 | 11 | resource "aws_subnet" "credhub_az2" { 12 | vpc_id = var.vpc_id 13 | cidr_block = var.credhub_cidr_az2 14 | availability_zone = var.credhub_az2 15 | 16 | tags = { 17 | Name = "${var.stack_description} (Credhub - ${var.credhub_cidr_az2})" 18 | } 19 | } 20 | 21 | resource "aws_route_table_association" "credhub_rta_az1" { 22 | subnet_id = aws_subnet.credhub_az1.id 23 | route_table_id = var.route_table_id_az1 24 | } 25 | 26 | resource "aws_route_table_association" "credhub_rta_az2" { 27 | subnet_id = aws_subnet.credhub_az2.id 28 | route_table_id = var.route_table_id_az2 29 | } 30 | -------------------------------------------------------------------------------- /terraform/modules/credhub/security-groups.tf: -------------------------------------------------------------------------------- 1 | /* 2 | * Variables required: 3 | * stack_description 4 | * vpc_id 5 | */ 6 | 7 | resource "aws_security_group" "credhub" { 8 | description = "Allow access to incoming credhub traffic" 9 | vpc_id = var.vpc_id 10 | 11 | tags = { 12 | Name = "${var.stack_description} - Incoming Credhub Traffic" 13 | } 14 | } 15 | 16 | resource "aws_security_group_rule" "self_reference" { 17 | type = "ingress" 18 | self = true 19 | from_port = 0 20 | to_port = 0 21 | protocol = -1 22 | security_group_id = aws_security_group.credhub.id 23 | } 24 | 25 | resource "aws_security_group_rule" "credhub" { 26 | type = "ingress" 27 | from_port = 8844 28 | to_port = 8845 29 | protocol = "tcp" 30 | cidr_blocks = ["0.0.0.0/0"] 31 | security_group_id = aws_security_group.credhub.id 32 | } 33 | 34 | resource "aws_security_group_rule" "outbound" { 35 | type = "egress" 36 | from_port = 0 37 | to_port = 0 38 | protocol = -1 39 | cidr_blocks = ["0.0.0.0/0"] 40 | security_group_id = aws_security_group.credhub.id 41 | } 42 | -------------------------------------------------------------------------------- /terraform/modules/credhub/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/credhub_v2/alb.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb_target_group" "credhub_target" { 2 | name = "${var.stack_description}-credhub" 3 | port = 8844 4 | protocol = "HTTPS" 5 | vpc_id = var.vpc_id 6 | 7 | health_check { 8 | healthy_threshold = 2 9 | unhealthy_threshold = 10 10 | timeout = 5 11 | interval = 30 12 | matcher = 200 13 | port = 8844 14 | path = "/health" 15 | protocol = "HTTPS" 16 | } 17 | 18 | stickiness { 19 | type = "lb_cookie" 20 | enabled = true 21 | } 22 | } 23 | 24 | resource "aws_lb_listener_rule" "credhub_listener_rule" { 25 | count = length(var.hosts) 26 | 27 | listener_arn = var.listener_arn 28 | 29 | action { 30 | type = "forward" 31 | target_group_arn = aws_lb_target_group.credhub_target.arn 32 | } 33 | 34 | condition { 35 | host_header { 36 | values = [element(var.hosts, count.index)] 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /terraform/modules/credhub_v2/network.tf: -------------------------------------------------------------------------------- 1 | resource "aws_subnet" "credhub_subnet" { 2 | count = length(var.credhub_availability_zones) 3 | 4 | vpc_id = var.vpc_id 5 | cidr_block = var.credhub_cidrs[count.index] 6 | availability_zone = var.credhub_availability_zones[count.index] 7 | 8 | tags = { 9 | Name = "${var.stack_description} (Credhub - ${var.credhub_availability_zones[count.index]})" 10 | } 11 | } 12 | 13 | resource "aws_route_table_association" "credhub_rta" { 14 | count = length(var.credhub_availability_zones) 15 | 16 | subnet_id = aws_subnet.credhub_subnet[count.index].id 17 | route_table_id = var.route_table_ids[count.index] 18 | } 19 | -------------------------------------------------------------------------------- /terraform/modules/credhub_v2/outputs.tf: -------------------------------------------------------------------------------- 1 | output "credhub_subnet_ids" { 2 | value = aws_subnet.credhub_subnet[*].id 3 | } 4 | 5 | output "credhub_subnet_cidrs" { 6 | value = aws_subnet.credhub_subnet[*].cidr_block 7 | } 8 | 9 | output "credhub_security_group" { 10 | value = aws_security_group.credhub.id 11 | } 12 | 13 | /* RDS credhub Instance */ 14 | output "credhub_rds_identifier" { 15 | value = module.rds_96.rds_identifier 16 | } 17 | 18 | output "credhub_rds_name" { 19 | value = module.rds_96.rds_name 20 | } 21 | 22 | output "credhub_rds_host" { 23 | value = module.rds_96.rds_host 24 | } 25 | 26 | output "credhub_rds_port" { 27 | value = module.rds_96.rds_port 28 | } 29 | 30 | output "credhub_rds_url" { 31 | value = module.rds_96.rds_url 32 | } 33 | 34 | output "credhub_rds_username" { 35 | value = module.rds_96.rds_username 36 | } 37 | 38 | output "credhub_rds_password" { 39 | value = module.rds_96.rds_password 40 | sensitive = true 41 | } 42 | 43 | output "credhub_lb_target_group" { 44 | value = aws_lb_target_group.credhub_target.name 45 | } 46 | -------------------------------------------------------------------------------- /terraform/modules/credhub_v2/rds.tf: -------------------------------------------------------------------------------- 1 | module "rds_96" { 2 | source = "../rds" 3 | 4 | stack_description = "credhub-${var.stack_description}" 5 | rds_db_name = var.rds_db_name 6 | rds_instance_type = var.rds_instance_type 7 | rds_db_size = var.rds_db_size 8 | rds_db_storage_type = var.rds_db_storage_type 9 | rds_db_iops = var.rds_db_iops 10 | rds_db_engine_version = var.rds_db_engine_version 11 | rds_username = var.rds_username 12 | rds_password = var.rds_password 13 | rds_subnet_group = var.rds_subnet_group 14 | rds_security_groups = var.rds_security_groups 15 | rds_parameter_group_name = var.rds_parameter_group_name 16 | rds_parameter_group_family = var.rds_parameter_group_family 17 | rds_allow_major_version_upgrade = var.rds_allow_major_version_upgrade 18 | rds_apply_immediately = var.rds_apply_immediately 19 | rds_multi_az = var.rds_multi_az 20 | rds_final_snapshot_identifier = var.rds_final_snapshot_identifier 21 | } 22 | -------------------------------------------------------------------------------- /terraform/modules/credhub_v2/security-groups.tf: -------------------------------------------------------------------------------- 1 | /* 2 | * Variables required: 3 | * stack_description 4 | * vpc_id 5 | */ 6 | 7 | resource "aws_security_group" "credhub" { 8 | description = "Allow access to incoming credhub traffic" 9 | vpc_id = var.vpc_id 10 | 11 | tags = { 12 | Name = "${var.stack_description} - Incoming Credhub Traffic" 13 | } 14 | } 15 | 16 | resource "aws_security_group_rule" "self_reference" { 17 | type = "ingress" 18 | self = true 19 | from_port = 0 20 | to_port = 0 21 | protocol = -1 22 | security_group_id = aws_security_group.credhub.id 23 | } 24 | 25 | resource "aws_security_group_rule" "credhub" { 26 | type = "ingress" 27 | from_port = 8844 28 | to_port = 8845 29 | protocol = "tcp" 30 | cidr_blocks = ["0.0.0.0/0"] 31 | security_group_id = aws_security_group.credhub.id 32 | } 33 | 34 | resource "aws_security_group_rule" "outbound" { 35 | type = "egress" 36 | from_port = 0 37 | to_port = 0 38 | protocol = -1 39 | cidr_blocks = ["0.0.0.0/0"] 40 | security_group_id = aws_security_group.credhub.id 41 | } 42 | -------------------------------------------------------------------------------- /terraform/modules/credhub_v2/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/csb/README.md: -------------------------------------------------------------------------------- 1 | # Module CSB 2 | 3 | Resources related to the Cloud Service Broker. 4 | 5 | See also https://github.com/cloud-gov/csb. 6 | 7 | ## Why two modules? 8 | 9 | The `iam` module contains the IAM policy that the broker uses to deploy resources on behalf of customers. This is distinct from the IAM policy in the `broker` module used by Cloud Foundry to pull the CSB image. Some brokerpaks must create resources in AWS Commercial, so both a Commercial and a GovCloud IAM user must be created. They are managed in a separate module for the following reasons: 10 | 11 | - To support deploying them to two separate partitions using two providers, without forcing the rest of the broker resources to specify `provider=`, since they will only ever be deployed to GovCloud. 12 | - To keep the policies together in the codebase, since they are related. (We could have split up the CSB resources by GovCloud vs Commercial, but the brokerpak-related policies would no longer all be in one place.) 13 | - To maintain a dedicated space for the policies, which are expected to grow as we add more brokerpaks. 14 | -------------------------------------------------------------------------------- /terraform/modules/csb/broker/main.tf: -------------------------------------------------------------------------------- 1 | // Use the RDS module instead of brokering a database inside Cloud Foundry. 2 | // Eventually the CSB itself will broker RDS, so this avoids a circular dependency. 3 | module "db" { 4 | source = "../../rds" 5 | 6 | stack_description = var.stack_description 7 | rds_instance_type = var.rds_instance_type 8 | rds_db_size = var.rds_db_size 9 | rds_db_engine = var.rds_db_engine 10 | rds_db_engine_version = var.rds_db_engine_version 11 | rds_db_name = var.rds_db_name 12 | rds_username = var.rds_username 13 | rds_password = var.rds_password 14 | rds_subnet_group = var.rds_subnet_group 15 | rds_security_groups = var.rds_security_groups 16 | rds_parameter_group_family = var.rds_parameter_group_family 17 | rds_allow_major_version_upgrade = var.rds_allow_major_version_upgrade 18 | rds_apply_immediately = var.rds_apply_immediately 19 | } 20 | -------------------------------------------------------------------------------- /terraform/modules/csb/broker/outputs.tf: -------------------------------------------------------------------------------- 1 | output "rds_host" { 2 | value = module.db.rds_host 3 | } 4 | 5 | output "rds_port" { 6 | value = module.db.rds_port 7 | } 8 | 9 | output "rds_url" { 10 | value = module.db.rds_url 11 | } 12 | 13 | output "rds_name" { 14 | value = module.db.rds_name 15 | } 16 | 17 | output "rds_username" { 18 | value = module.db.rds_username 19 | } 20 | 21 | output "rds_password" { 22 | value = module.db.rds_password 23 | sensitive = true 24 | } 25 | -------------------------------------------------------------------------------- /terraform/modules/csb/broker/variables.tf: -------------------------------------------------------------------------------- 1 | variable "stack_description" { 2 | type = string 3 | description = "Like development, staging, or production." 4 | } 5 | 6 | # RDS variables 7 | 8 | variable "rds_instance_type" { 9 | type = string 10 | default = "db.t3.small" 11 | } 12 | 13 | variable "rds_db_size" { 14 | type = number 15 | default = 20 16 | } 17 | 18 | variable "rds_db_name" { 19 | type = string 20 | default = "csb" 21 | } 22 | 23 | variable "rds_db_engine" { 24 | type = string 25 | default = "mysql" 26 | } 27 | 28 | variable "rds_db_engine_version" { 29 | type = string 30 | default = "8.0" 31 | } 32 | 33 | variable "rds_parameter_group_family" { 34 | type = string 35 | default = "mysql8.0" 36 | } 37 | 38 | variable "rds_username" { 39 | type = string 40 | default = "csb" 41 | } 42 | 43 | variable "rds_password" { 44 | type = string 45 | sensitive = true 46 | } 47 | 48 | variable "rds_subnet_group" { 49 | } 50 | 51 | variable "rds_security_groups" { 52 | type = list(string) 53 | } 54 | 55 | variable "rds_apply_immediately" { 56 | default = "false" 57 | } 58 | 59 | variable "rds_allow_major_version_upgrade" { 60 | default = "false" 61 | } 62 | -------------------------------------------------------------------------------- /terraform/modules/csb/broker/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | cloudfoundry = { 9 | source = "cloudfoundry-community/cloudfoundry" 10 | version = "< 1.0" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /terraform/modules/csb/iam/commercial/outputs.tf: -------------------------------------------------------------------------------- 1 | output "username" { 2 | value = aws_iam_user.csb.name 3 | } 4 | 5 | output "access_key_id_prev" { 6 | value = "" 7 | } 8 | 9 | output "secret_access_key_prev" { 10 | value = "" 11 | sensitive = true 12 | } 13 | 14 | output "access_key_id_curr" { 15 | value = aws_iam_access_key.csb.id 16 | } 17 | 18 | output "secret_access_key_curr" { 19 | value = aws_iam_access_key.csb.secret 20 | sensitive = true 21 | } 22 | -------------------------------------------------------------------------------- /terraform/modules/csb/iam/commercial/variables.tf: -------------------------------------------------------------------------------- 1 | variable "stack_description" { 2 | type = string 3 | description = "Like development, staging, or production." 4 | } 5 | -------------------------------------------------------------------------------- /terraform/modules/csb/iam/commercial/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/csb/iam/govcloud/concourse.tf: -------------------------------------------------------------------------------- 1 | data "aws_iam_policy_document" "concourse" { 2 | statement { 3 | effect = "Allow" 4 | actions = [ 5 | "sns:GetSubscriptionAttributes", 6 | "sns:SetSubscriptionAttributes", 7 | "sns:Subscribe", 8 | "sns:Unsubscribe", 9 | ] 10 | resources = [var.sns_platform_notification_topic_arn] 11 | } 12 | } 13 | 14 | resource "aws_iam_policy" "concourse" { 15 | name = "${var.stack_description}-csb-concourse" 16 | description = "Used by the Concourse pipeline `csb`, which uses Terraform to deploy the CSB and CSB Helper. The pipeline manages a subscription to the platform notifications topic on behalf of the CSB Helper." 17 | policy = data.aws_iam_policy_document.concourse.json 18 | } 19 | 20 | resource "aws_iam_user" "concourse" { 21 | name = "${var.stack_description}-concourse-csb" 22 | } 23 | 24 | resource "aws_iam_user_policy_attachment" "concourse" { 25 | user = aws_iam_user.concourse.name 26 | policy_arn = aws_iam_policy.concourse.arn 27 | } 28 | 29 | resource "aws_iam_access_key" "concourse" { 30 | user = aws_iam_user.concourse.name 31 | } 32 | -------------------------------------------------------------------------------- /terraform/modules/csb/iam/govcloud/csb_helper.tf: -------------------------------------------------------------------------------- 1 | data "aws_iam_policy_document" "csb_helper" { 2 | statement { 3 | effect = "Allow" 4 | actions = ["ses:UpdateConfigurationSetSendingEnabled"] 5 | resources = ["*"] 6 | } 7 | 8 | statement { 9 | effect = "Allow" 10 | actions = [ 11 | "sns:ConfirmSubscription", 12 | "sns:GetSubscriptionAttributes", 13 | "sns:GetTopicAttributes", 14 | ] 15 | resources = [var.sns_platform_notification_topic_arn] 16 | } 17 | } 18 | 19 | resource "aws_iam_policy" "csb_helper" { 20 | name = "${var.stack_description}-csb-helper" 21 | description = "Policy for the CSB Helper web service, which supports the Cloud Service Broker." 22 | policy = data.aws_iam_policy_document.csb_helper.json 23 | } 24 | 25 | resource "aws_iam_user" "csb_helper" { 26 | name = "${var.stack_description}-csb-helper" 27 | } 28 | 29 | resource "aws_iam_access_key" "csb_helper" { 30 | user = aws_iam_user.csb_helper.name 31 | } 32 | 33 | resource "aws_iam_user_policy_attachment" "csb_helper" { 34 | user = aws_iam_user.csb_helper.name 35 | policy_arn = aws_iam_policy.csb_helper.arn 36 | } 37 | -------------------------------------------------------------------------------- /terraform/modules/csb/iam/govcloud/ecr.tf: -------------------------------------------------------------------------------- 1 | data "terraform_remote_state" "ecr" { 2 | backend = "s3" 3 | 4 | config = { 5 | bucket = var.ecr_remote_state_bucket 6 | region = var.ecr_remote_state_region 7 | key = "${var.ecr_stack_name}/terraform.tfstate" 8 | } 9 | } 10 | 11 | locals { 12 | csb_ecr_repository_arn = data.terraform_remote_state.ecr.outputs.repository_arns["cg-csb"] 13 | csb_helper_ecr_repository_arn = data.terraform_remote_state.ecr.outputs.repository_arns["csb-helper"] 14 | } 15 | 16 | // A user with ECR pull permissions so Cloud Foundry can pull the CSB image. 17 | module "ecr_user" { 18 | source = "../../../iam_user/ecr_pull_user" 19 | username = "${var.stack_description}-csb-ecr" 20 | repository_arns = [local.csb_ecr_repository_arn, local.csb_helper_ecr_repository_arn] 21 | } 22 | -------------------------------------------------------------------------------- /terraform/modules/csb/iam/govcloud/variables.tf: -------------------------------------------------------------------------------- 1 | variable "stack_description" { 2 | type = string 3 | description = "Like development, staging, or production." 4 | } 5 | 6 | variable "sns_platform_notification_topic_arn" { 7 | type = string 8 | description = "Required to give the Concourse IAM user permission to subscribe the CSB Helper to the topic." 9 | } 10 | 11 | variable "ecr_remote_state_bucket" { 12 | type = string 13 | description = "Required to resolve the docker image repository ARNs." 14 | } 15 | 16 | variable "ecr_remote_state_region" { 17 | type = string 18 | description = "Required to resolve the docker image repository ARNs." 19 | } 20 | 21 | variable "ecr_stack_name" { 22 | type = string 23 | description = "The name of the stack that configures ECR. Required to resolve the docker image repository ARNs." 24 | } 25 | -------------------------------------------------------------------------------- /terraform/modules/csb/iam/govcloud/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/cvd_mirror/variables.tf: -------------------------------------------------------------------------------- 1 | variable "bucket" { 2 | } 3 | 4 | variable "versioning" { 5 | default = "false" 6 | } 7 | 8 | variable "force_destroy" { 9 | default = "false" 10 | } 11 | 12 | variable "aws_partition" { 13 | } 14 | -------------------------------------------------------------------------------- /terraform/modules/cvd_mirror/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/cvd_mirror_v2/variables.tf: -------------------------------------------------------------------------------- 1 | variable "bucket" { 2 | } 3 | 4 | variable "versioning" { 5 | default = "false" 6 | } 7 | 8 | variable "force_destroy" { 9 | default = "false" 10 | } 11 | 12 | variable "aws_partition" { 13 | } 14 | -------------------------------------------------------------------------------- /terraform/modules/cvd_mirror_v2/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/defect_dojo/elb.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb_target_group" "defectdojo_target" { 2 | name = "${var.stack_description}-dojo-${var.defectdojo_az1}" 3 | port = 8080 4 | protocol = "HTTP" 5 | vpc_id = var.vpc_id 6 | 7 | health_check { 8 | healthy_threshold = 2 9 | unhealthy_threshold = 10 10 | timeout = 5 11 | interval = 30 12 | matcher = 200 13 | path = "/login?force_login_form" 14 | } 15 | 16 | stickiness { 17 | type = "lb_cookie" 18 | enabled = true 19 | } 20 | } 21 | 22 | resource "aws_lb_listener_rule" "defectdojo_listener_rule" { 23 | count = length(var.hosts) 24 | 25 | listener_arn = var.listener_arn 26 | 27 | action { 28 | type = "forward" 29 | target_group_arn = aws_lb_target_group.defectdojo_target.arn 30 | } 31 | 32 | condition { 33 | host_header { 34 | values = [element(var.hosts, count.index)] 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /terraform/modules/defect_dojo/network.tf: -------------------------------------------------------------------------------- 1 | resource "aws_subnet" "defectdojo_az1" { 2 | vpc_id = var.vpc_id 3 | cidr_block = var.defectdojo_cidr_az1 4 | availability_zone = var.defectdojo_az1 5 | 6 | tags = { 7 | Name = "${var.stack_description} (Defect Dojo - ${var.defectdojo_cidr_az1})" 8 | } 9 | } 10 | 11 | resource "aws_subnet" "defectdojo_az2" { 12 | vpc_id = var.vpc_id 13 | cidr_block = var.defectdojo_cidr_az2 14 | availability_zone = var.defectdojo_az2 15 | 16 | tags = { 17 | Name = "${var.stack_description} (Defect Dojo - ${var.defectdojo_cidr_az2})" 18 | } 19 | } 20 | 21 | resource "aws_route_table_association" "defectdojo_rta_az1" { 22 | subnet_id = aws_subnet.defectdojo_az1.id 23 | route_table_id = var.route_table_id_az1 24 | } 25 | 26 | resource "aws_route_table_association" "defectdojo_rta_az2" { 27 | subnet_id = aws_subnet.defectdojo_az2.id 28 | route_table_id = var.route_table_id_az2 29 | } 30 | -------------------------------------------------------------------------------- /terraform/modules/defect_dojo/security-groups.tf: -------------------------------------------------------------------------------- 1 | resource "aws_security_group" "defectdojo" { 2 | description = "Allow access to incoming defect dojo traffic" 3 | vpc_id = var.vpc_id 4 | 5 | tags = { 6 | Name = "${var.stack_description} - Incoming Defect Dojo Traffic" 7 | } 8 | } 9 | 10 | resource "aws_security_group_rule" "self_reference" { 11 | type = "ingress" 12 | self = true 13 | from_port = 0 14 | to_port = 0 15 | protocol = -1 16 | security_group_id = aws_security_group.defectdojo.id 17 | } 18 | 19 | resource "aws_security_group_rule" "defectdojo_web" { 20 | type = "ingress" 21 | from_port = 8080 22 | to_port = 8080 23 | protocol = "tcp" 24 | cidr_blocks = ["0.0.0.0/0"] 25 | security_group_id = aws_security_group.defectdojo.id 26 | } 27 | 28 | resource "aws_security_group_rule" "outbound" { 29 | type = "egress" 30 | from_port = 0 31 | to_port = 0 32 | protocol = -1 33 | cidr_blocks = ["0.0.0.0/0"] 34 | security_group_id = aws_security_group.defectdojo.id 35 | } 36 | -------------------------------------------------------------------------------- /terraform/modules/defect_dojo/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/diego/outputs.tf: -------------------------------------------------------------------------------- 1 | /* Diego Proxy ELB */ 2 | 3 | output "diego_elb_name" { 4 | value = aws_elb.diego_elb_main.name 5 | } 6 | 7 | output "diego_elb_dns_name" { 8 | value = aws_elb.diego_elb_main.dns_name 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/diego/variables.tf: -------------------------------------------------------------------------------- 1 | variable "stack_description" { 2 | } 3 | 4 | variable "az1" { 5 | default = "us-gov-west-1a" 6 | } 7 | 8 | variable "az2" { 9 | default = "us-gov-west-1b" 10 | } 11 | 12 | variable "vpc_id" { 13 | } 14 | 15 | variable "elb_subnets" { 16 | type = list(string) 17 | } 18 | 19 | variable "ingress_cidrs" { 20 | type = list(string) 21 | default = ["0.0.0.0"] 22 | } 23 | 24 | variable "log_bucket_name" { 25 | } 26 | -------------------------------------------------------------------------------- /terraform/modules/diego/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/dns/outputs.tf: -------------------------------------------------------------------------------- 1 | output "axfr_security_group" { 2 | value = aws_security_group.dns_axfr.id 3 | } 4 | 5 | output "public_security_group" { 6 | value = aws_security_group.dns_public.id 7 | } 8 | -------------------------------------------------------------------------------- /terraform/modules/dns/variables.tf: -------------------------------------------------------------------------------- 1 | variable "stack_description" { 2 | } 3 | 4 | variable "vpc_id" { 5 | } 6 | -------------------------------------------------------------------------------- /terraform/modules/dns/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/dns_logging/resolver_logging.tf: -------------------------------------------------------------------------------- 1 | resource "aws_cloudwatch_log_group" "query_resolver_logs" { 2 | name = "${var.stack_description}-query-resolver-logs" 3 | # Keep for 5 years. This is the only option that is greater than the 4 | # minimum requirement of 30 months for M-21-31 Passive DNS data. 5 | retention_in_days = 1096 6 | 7 | tags = { 8 | Environment = var.stack_description 9 | } 10 | } 11 | 12 | 13 | resource "aws_route53_resolver_query_log_config" "resolver_config" { 14 | name = "${var.stack_description}-query-resolver-logs" 15 | destination_arn = aws_cloudwatch_log_group.query_resolver_logs.arn 16 | 17 | tags = { 18 | Environment = var.stack_description 19 | } 20 | } 21 | 22 | resource "aws_route53_resolver_query_log_config_association" "resolver_config_association" { 23 | resolver_query_log_config_id = aws_route53_resolver_query_log_config.resolver_config.id 24 | resource_id = var.vpc_id 25 | } 26 | -------------------------------------------------------------------------------- /terraform/modules/dns_logging/variables.tf: -------------------------------------------------------------------------------- 1 | variable "stack_description" { 2 | type = string 3 | } 4 | 5 | variable "aws_partition" { 6 | type = string 7 | } 8 | 9 | variable "vpc_id" { 10 | type = string 11 | } 12 | -------------------------------------------------------------------------------- /terraform/modules/elasticache_broker_network/elb.tf: -------------------------------------------------------------------------------- 1 | resource "aws_elb" "elasticache_elb" { 2 | name = "${var.stack_description}-elasticache-broker" 3 | subnets = var.elb_subnets 4 | security_groups = var.elb_security_groups 5 | internal = true 6 | 7 | listener { 8 | lb_port = 80 9 | lb_protocol = "HTTP" 10 | instance_port = 80 11 | instance_protocol = "HTTP" 12 | } 13 | 14 | health_check { 15 | healthy_threshold = 2 16 | unhealthy_threshold = 3 17 | interval = 10 18 | timeout = 5 19 | target = "HTTP:80/healthcheck" 20 | } 21 | 22 | tags = { 23 | Name = "${var.stack_description}-elasticache-broker" 24 | } 25 | 26 | access_logs { 27 | bucket = var.log_bucket_name 28 | bucket_prefix = var.stack_description 29 | enabled = true 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /terraform/modules/elasticache_broker_network/outputs.tf: -------------------------------------------------------------------------------- 1 | output "elasticache_subnet_az1" { 2 | value = aws_subnet.az1_elasticache.id 3 | } 4 | 5 | output "elasticache_subnet_az2" { 6 | value = aws_subnet.az2_elasticache.id 7 | } 8 | 9 | output "elasticache_private_cidr_1" { 10 | value = aws_subnet.az1_elasticache.cidr_block 11 | } 12 | 13 | output "elasticache_private_cidr_2" { 14 | value = aws_subnet.az2_elasticache.cidr_block 15 | } 16 | 17 | output "elasticache_subnet_group" { 18 | value = aws_elasticache_subnet_group.elasticache.id 19 | } 20 | 21 | output "elasticache_redis_security_group" { 22 | value = aws_security_group.elasticache_redis.id 23 | } 24 | 25 | output "elasticache_elb_dns_name" { 26 | value = aws_elb.elasticache_elb.dns_name 27 | } 28 | 29 | output "elasticache_elb_name" { 30 | value = aws_elb.elasticache_elb.name 31 | } 32 | -------------------------------------------------------------------------------- /terraform/modules/elasticache_broker_network/sg_redis.tf: -------------------------------------------------------------------------------- 1 | resource "aws_security_group" "elasticache_redis" { 2 | description = "Allow access to incoming redis traffic" 3 | vpc_id = var.vpc_id 4 | 5 | ingress { 6 | from_port = 6379 7 | to_port = 6379 8 | protocol = "tcp" 9 | security_groups = var.security_groups 10 | } 11 | 12 | egress { 13 | from_port = 0 14 | to_port = 0 15 | protocol = "-1" 16 | security_groups = var.security_groups 17 | } 18 | 19 | tags = { 20 | Name = "${var.stack_description} - Incoming Redis Traffic" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /terraform/modules/elasticache_broker_network/subnets.tf: -------------------------------------------------------------------------------- 1 | resource "aws_subnet" "az1_elasticache" { 2 | vpc_id = var.vpc_id 3 | cidr_block = var.elasticache_private_cidr_1 4 | availability_zone = var.az1 5 | 6 | tags = { 7 | Name = "${var.stack_description} (Elasticache Broker AZ1)" 8 | } 9 | } 10 | 11 | resource "aws_subnet" "az2_elasticache" { 12 | vpc_id = var.vpc_id 13 | cidr_block = var.elasticache_private_cidr_2 14 | availability_zone = var.az2 15 | 16 | tags = { 17 | Name = "${var.stack_description} (Elasticache Broker AZ2)" 18 | } 19 | } 20 | 21 | resource "aws_elasticache_subnet_group" "elasticache" { 22 | name = var.stack_description 23 | description = "${var.stack_description} (Multi-AZ Subnet Group)" 24 | subnet_ids = [aws_subnet.az1_elasticache.id, aws_subnet.az2_elasticache.id] 25 | } 26 | 27 | resource "aws_route_table_association" "az1_elasticache_rta" { 28 | subnet_id = aws_subnet.az1_elasticache.id 29 | route_table_id = var.az1_route_table 30 | } 31 | 32 | resource "aws_route_table_association" "az2_elasticache_rta" { 33 | subnet_id = aws_subnet.az2_elasticache.id 34 | route_table_id = var.az2_route_table 35 | } 36 | -------------------------------------------------------------------------------- /terraform/modules/elasticache_broker_network/variables.tf: -------------------------------------------------------------------------------- 1 | variable "stack_description" { 2 | } 3 | 4 | variable "az1" { 5 | default = "us-gov-west-1a" 6 | } 7 | 8 | variable "az2" { 9 | default = "us-gov-west-1b" 10 | } 11 | 12 | variable "elasticache_private_cidr_1" { 13 | } 14 | 15 | variable "elasticache_private_cidr_2" { 16 | } 17 | 18 | variable "az1_route_table" { 19 | } 20 | 21 | variable "az2_route_table" { 22 | } 23 | 24 | variable "vpc_id" { 25 | } 26 | 27 | variable "security_groups" { 28 | type = list(string) 29 | } 30 | 31 | variable "elb_subnets" { 32 | type = list(string) 33 | } 34 | 35 | variable "elb_security_groups" { 36 | type = list(string) 37 | } 38 | 39 | variable "log_bucket_name" { 40 | } 41 | -------------------------------------------------------------------------------- /terraform/modules/elasticache_broker_network/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/elasticache_replication_group/elasticache.tf: -------------------------------------------------------------------------------- 1 | resource "random_password" "password" { 2 | length = 64 3 | # see https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/auth.html#auth-overview 4 | override_special = "!&#$^<>-" 5 | } 6 | 7 | resource "aws_elasticache_replication_group" "replication_group" { 8 | replication_group_id = "${var.cluster_name}-cluster" 9 | description = "${var.cluster_name} cluster" 10 | node_type = var.node_type 11 | port = 6379 12 | auto_minor_version_upgrade = true 13 | auth_token = random_password.password.result 14 | 15 | engine = var.engine 16 | engine_version = var.engine_version 17 | num_cache_clusters = var.num_cache_clusters 18 | 19 | automatic_failover_enabled = true 20 | multi_az_enabled = true 21 | 22 | transit_encryption_enabled = true 23 | at_rest_encryption_enabled = true 24 | 25 | subnet_group_name = var.subnet_group_name 26 | security_group_ids = var.security_group_ids 27 | } 28 | -------------------------------------------------------------------------------- /terraform/modules/elasticache_replication_group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "primary_endpoint" { 2 | value = aws_elasticache_replication_group.replication_group.primary_endpoint_address 3 | } 4 | 5 | output "password" { 6 | value = random_password.password.result 7 | sensitive = true 8 | } 9 | -------------------------------------------------------------------------------- /terraform/modules/elasticache_replication_group/variables.tf: -------------------------------------------------------------------------------- 1 | variable "cluster_name" { 2 | type = string 3 | description = "Name of the cluster" 4 | } 5 | 6 | variable "node_type" { 7 | type = string 8 | default = "cache.t3.small" 9 | description = "Node type to use for Elasticache cluster" 10 | } 11 | 12 | variable "engine" { 13 | type = string 14 | description = "Engine to use for Elasticache cluster (e.g. redis, valkey)" 15 | default = "redis" 16 | } 17 | 18 | variable "engine_version" { 19 | type = string 20 | description = "Engine version use for Elasticache cluster" 21 | default = "7.1" 22 | } 23 | 24 | variable "num_cache_clusters" { 25 | type = number 26 | description = "Number of cache clusters to use" 27 | default = 3 28 | } 29 | 30 | variable "subnet_group_name" { 31 | type = string 32 | description = "Name of subnet group to use for Elasticache cluster" 33 | } 34 | 35 | variable "security_group_ids" { 36 | type = list(string) 37 | description = "List of security group IDs to apply to the Elasticache cluster" 38 | } 39 | -------------------------------------------------------------------------------- /terraform/modules/elasticsearch_broker/log_group.tf: -------------------------------------------------------------------------------- 1 | resource "aws_cloudwatch_log_group" "audit_log" { 2 | name = "${var.stack_description}-elasticsearch_broker_audit_log" 3 | # Lowest allowed value that fulfills M-21-31 reqs of storing for 30 months 4 | retention_in_days = 1096 5 | } 6 | -------------------------------------------------------------------------------- /terraform/modules/elasticsearch_broker/outputs.tf: -------------------------------------------------------------------------------- 1 | output "elasticsearch_subnet1_az1" { 2 | value = aws_subnet.az1_elasticsearch.id 3 | } 4 | 5 | output "elasticsearch_subnet2_az2" { 6 | value = aws_subnet.az2_elasticsearch.id 7 | } 8 | 9 | output "elasticsearch_subnet3_az1" { 10 | value = aws_subnet.az3_elasticsearch.id 11 | } 12 | 13 | output "elasticsearch_subnet4_az2" { 14 | value = aws_subnet.az4_elasticsearch.id 15 | } 16 | 17 | output "elasticsearch_private_cidr_1" { 18 | value = aws_subnet.az1_elasticsearch.cidr_block 19 | } 20 | 21 | output "elasticsearch_private_cidr_2" { 22 | value = aws_subnet.az2_elasticsearch.cidr_block 23 | } 24 | 25 | output "elasticsearch_private_cidr_3" { 26 | value = aws_subnet.az3_elasticsearch.cidr_block 27 | } 28 | 29 | output "elasticsearch_private_cidr_4" { 30 | value = aws_subnet.az4_elasticsearch.cidr_block 31 | } 32 | 33 | output "elasticsearch_security_group" { 34 | value = aws_security_group.elasticsearch.id 35 | } 36 | output "elasticsearch_log_group_audit" { 37 | value = aws_cloudwatch_log_group.audit_log.arn 38 | } 39 | -------------------------------------------------------------------------------- /terraform/modules/elasticsearch_broker/security_group.tf: -------------------------------------------------------------------------------- 1 | resource "aws_security_group" "elasticsearch" { 2 | description = "Allow access to incoming elasticsearch traffic" 3 | vpc_id = var.vpc_id 4 | 5 | ingress { 6 | from_port = 443 7 | to_port = 443 8 | protocol = "tcp" 9 | security_groups = var.security_groups 10 | } 11 | 12 | egress { 13 | from_port = 0 14 | to_port = 0 15 | protocol = "-1" 16 | security_groups = var.security_groups 17 | } 18 | 19 | tags = { 20 | Name = "${var.stack_description} - Incoming Elasticsearch Traffic" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /terraform/modules/elasticsearch_broker/variables.tf: -------------------------------------------------------------------------------- 1 | variable "stack_description" { 2 | } 3 | 4 | variable "az1" { 5 | default = "us-gov-west-1a" 6 | } 7 | 8 | variable "az2" { 9 | default = "us-gov-west-1b" 10 | } 11 | 12 | variable "elasticsearch_private_cidr_1" { 13 | } 14 | 15 | variable "elasticsearch_private_cidr_2" { 16 | } 17 | 18 | variable "elasticsearch_private_cidr_3" { 19 | } 20 | 21 | variable "elasticsearch_private_cidr_4" { 22 | } 23 | 24 | variable "az1_route_table" { 25 | } 26 | 27 | variable "az2_route_table" { 28 | } 29 | 30 | variable "vpc_id" { 31 | } 32 | 33 | variable "security_groups" { 34 | type = list(string) 35 | } 36 | -------------------------------------------------------------------------------- /terraform/modules/elasticsearch_broker/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/environment_dns/variables.tf: -------------------------------------------------------------------------------- 1 | variable "zone_id" { 2 | 3 | } 4 | 5 | variable "app_subdomain" { 6 | 7 | } 8 | variable "admin_subdomain" { 9 | 10 | } 11 | 12 | variable "domain" { 13 | 14 | } 15 | 16 | variable "stack_name" { 17 | 18 | } 19 | 20 | variable "alb_zone_id" { 21 | default = "Z33AYJ8TM3BH4J" # this is for us-gov-west-1. See others here: https://docs.aws.amazon.com/general/latest/gr/elb.html 22 | } 23 | 24 | variable "nlb_zone_id" { 25 | default = "ZMG1MZ2THAWF1" # this is for us-gov-west-1. See others here: https://docs.aws.amazon.com/general/latest/gr/elb.html 26 | } 27 | variable "remote_state_bucket" { 28 | 29 | } 30 | variable "remote_state_region" { 31 | 32 | } 33 | -------------------------------------------------------------------------------- /terraform/modules/environment_dns/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/external_domain_broker/cloudwatch.tf: -------------------------------------------------------------------------------- 1 | resource "aws_cloudwatch_log_group" "external_domain_waf_logs" { 2 | name = "aws-waf-logs-external-domain-broker-${var.stack_description}" 3 | retention_in_days = 365 4 | } 5 | -------------------------------------------------------------------------------- /terraform/modules/external_domain_broker/outputs.tf: -------------------------------------------------------------------------------- 1 | output "username" { 2 | value = aws_iam_user.iam_user.name 3 | } 4 | 5 | output "access_key_id_prev" { 6 | value = "" 7 | } 8 | 9 | output "secret_access_key_prev" { 10 | value = "" 11 | } 12 | 13 | output "access_key_id_curr" { 14 | value = aws_iam_access_key.iam_access_key_v3.id 15 | } 16 | 17 | output "secret_access_key_curr" { 18 | value = aws_iam_access_key.iam_access_key_v3.secret 19 | } 20 | 21 | output "waf_rate_limit_group_arn" { 22 | value = aws_wafv2_rule_group.rate_limit_group.arn 23 | } 24 | -------------------------------------------------------------------------------- /terraform/modules/external_domain_broker/route53.tf: -------------------------------------------------------------------------------- 1 | # These resources are for https://github.com/cloud-gov/external-domain-broker 2 | 3 | resource "aws_route53_zone" "zone" { 4 | name = "external-domains-${var.stack_description}.cloud.gov" 5 | comment = "Hosts TXT and CNAME records for the external-domain-broker" 6 | } 7 | 8 | data "aws_route53_zone" "cloud_gov" { 9 | name = "cloud.gov" 10 | } 11 | 12 | resource "aws_route53_record" "record" { 13 | name = aws_route53_zone.zone.name 14 | zone_id = data.aws_route53_zone.cloud_gov.zone_id 15 | type = "NS" 16 | ttl = "60" 17 | 18 | records = [ 19 | aws_route53_zone.zone.name_servers[0], 20 | aws_route53_zone.zone.name_servers[1], 21 | aws_route53_zone.zone.name_servers[2], 22 | aws_route53_zone.zone.name_servers[3], 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /terraform/modules/external_domain_broker/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/external_domain_broker_govcloud/outputs.tf: -------------------------------------------------------------------------------- 1 | output "username" { 2 | value = aws_iam_user.iam_user.name 3 | } 4 | 5 | output "access_key_id_prev" { 6 | value = "" 7 | } 8 | 9 | output "secret_access_key_prev" { 10 | value = "" 11 | } 12 | 13 | output "access_key_id_curr" { 14 | value = aws_iam_access_key.iam_access_key_v3.id 15 | } 16 | 17 | output "secret_access_key_curr" { 18 | value = aws_iam_access_key.iam_access_key_v3.secret 19 | } 20 | -------------------------------------------------------------------------------- /terraform/modules/external_domain_broker_govcloud/variables.tf: -------------------------------------------------------------------------------- 1 | variable "account_id" { 2 | } 3 | 4 | variable "stack_description" { 5 | } 6 | 7 | variable "aws_partition" { 8 | type = string 9 | description = "AWS partition where the resources are deployed" 10 | } 11 | 12 | variable "aws_region" { 13 | type = string 14 | description = "AWS region where the resources are deployed" 15 | } 16 | -------------------------------------------------------------------------------- /terraform/modules/external_domain_broker_govcloud/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/external_domain_broker_loadbalancer_group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "domains_lbgroup_names" { 2 | value = aws_lb.domains_lbgroup.*.name 3 | } 4 | 5 | output "domains_lbgroup_target_group_apps_https_names" { 6 | value = aws_lb_target_group.domains_lbgroup_apps_https.*.name 7 | } 8 | 9 | output "domains_lbgroup_listener_arns" { 10 | value = aws_lb_listener.domains_lbgroup_https.*.arn 11 | } 12 | 13 | output "domains_lbgroup_target_group_logstash_https_names" { 14 | value = aws_lb_target_group.domains_lbgroup_logstash_https.*.name 15 | } 16 | 17 | output "domains_lbgroup_target_group_gr_apps_https_names" { 18 | value = aws_lb_target_group.domains_lbgroup_gr_apps_https.*.name 19 | } 20 | 21 | output "domains_lbgroup_target_group_gr_logstash_https_names" { 22 | value = aws_lb_target_group.domains_lbgroup_gr_logstash_https.*.name 23 | } 24 | -------------------------------------------------------------------------------- /terraform/modules/external_domain_broker_loadbalancer_group/variables.tf: -------------------------------------------------------------------------------- 1 | variable "stack_description" { 2 | 3 | } 4 | 5 | variable "domains_lbgroup_count" { 6 | default = 2 7 | } 8 | 9 | variable "elb_bucket_name" { 10 | } 11 | 12 | variable "subnets" { 13 | 14 | } 15 | 16 | variable "security_groups" { 17 | 18 | } 19 | 20 | variable "logstash_hosts" { 21 | 22 | } 23 | 24 | variable "vpc_id" { 25 | 26 | } 27 | 28 | variable "waf_arn" { 29 | 30 | } 31 | 32 | variable "wildcard_arn" { 33 | 34 | } 35 | 36 | variable "loadbalancer_forward_original_weight" { 37 | type = number 38 | description = "Weight of traffic to send to original target groups" 39 | default = 100 40 | } 41 | 42 | variable "loadbalancer_forward_new_weight" { 43 | type = number 44 | description = "Weight of traffic to send to original target groups" 45 | default = 0 46 | } 47 | 48 | variable "aws_lb_listener_ssl_policy" { 49 | type = string 50 | default = "ELBSecurityPolicy-TLS13-1-2-Ext1-2021-06" 51 | } 52 | -------------------------------------------------------------------------------- /terraform/modules/external_domain_broker_loadbalancer_group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/external_domain_broker_tests/outputs.tf: -------------------------------------------------------------------------------- 1 | output "username" { 2 | value = aws_iam_user.iam_user.name 3 | } 4 | 5 | output "access_key_id_prev" { 6 | value = "" 7 | } 8 | 9 | output "secret_access_key_prev" { 10 | value = "" 11 | } 12 | 13 | output "access_key_id_curr" { 14 | value = aws_iam_access_key.iam_access_key_v1.id 15 | } 16 | 17 | output "secret_access_key_curr" { 18 | value = aws_iam_access_key.iam_access_key_v1.secret 19 | } 20 | -------------------------------------------------------------------------------- /terraform/modules/external_domain_broker_tests/variables.tf: -------------------------------------------------------------------------------- 1 | variable "aws_partition" { 2 | } 3 | 4 | variable "stack_description" { 5 | } 6 | -------------------------------------------------------------------------------- /terraform/modules/external_domain_broker_tests/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | aws = { 5 | source = "hashicorp/aws" 6 | version = "< 6.0.0" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/modules/iam_role/outputs.tf: -------------------------------------------------------------------------------- 1 | output "role_name" { 2 | value = aws_iam_role.iam_role.name 3 | } 4 | 5 | output "profile_name" { 6 | value = aws_iam_instance_profile.iam_profile.name 7 | } 8 | -------------------------------------------------------------------------------- /terraform/modules/iam_role/role.tf: -------------------------------------------------------------------------------- 1 | resource "aws_iam_role" "iam_role" { 2 | name = var.role_name 3 | path = var.role_path 4 | assume_role_policy = var.iam_assume_role_policy 5 | } 6 | 7 | resource "aws_iam_instance_profile" "iam_profile" { 8 | name = var.role_name 9 | role = aws_iam_role.iam_role.name 10 | } 11 | 12 | resource "aws_iam_role_policy" "iam_policy" { 13 | count = var.iam_policy != "" ? 1 : 0 14 | name = var.role_name 15 | policy = var.iam_policy 16 | role = aws_iam_role.iam_role.name 17 | } 18 | -------------------------------------------------------------------------------- /terraform/modules/iam_role/variables.tf: -------------------------------------------------------------------------------- 1 | variable "role_name" { 2 | } 3 | 4 | variable "role_path" { 5 | default = "/bosh-passed/" 6 | } 7 | 8 | variable "iam_policy" { 9 | default = "" 10 | } 11 | 12 | variable "iam_assume_role_policy" { 13 | default = < v.arn } 3 | } 4 | -------------------------------------------------------------------------------- /terraform/stacks/ecr/versions.tf: -------------------------------------------------------------------------------- 1 | 2 | terraform { 3 | required_version = ">= 0.15" 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "< 6.0.0" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /terraform/stacks/external/versions.tf: -------------------------------------------------------------------------------- 1 | ../main/versions.tf -------------------------------------------------------------------------------- /terraform/stacks/main/buckets.tf: -------------------------------------------------------------------------------- 1 | module "bosh_blobstore_bucket" { 2 | source = "../../modules/s3_bucket/encrypted_bucket" 3 | bucket = var.blobstore_bucket_name 4 | aws_partition = data.aws_partition.current.partition 5 | force_destroy = "true" 6 | server_side_encryption = var.bosh_blobstore_sse 7 | } 8 | 9 | module "log_bucket" { 10 | source = "../../modules/log_bucket" 11 | aws_partition = data.aws_partition.current.partition 12 | log_bucket_name = "${var.stack_description}-elb-logs" 13 | aws_region = data.aws_region.current.name 14 | } 15 | -------------------------------------------------------------------------------- /terraform/stacks/main/versions.tf: -------------------------------------------------------------------------------- 1 | 2 | terraform { 3 | required_version = ">= 0.15" 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "< 6.0.0" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /terraform/stacks/managedaccount/outputs.tf: -------------------------------------------------------------------------------- 1 | output "tf_role_arn" { 2 | value = aws_iam_role.tfrole.arn 3 | } 4 | 5 | output "cert_role_arn" { 6 | value = aws_iam_role.certuploadrole.arn 7 | } 8 | -------------------------------------------------------------------------------- /terraform/stacks/managedaccount/variables.tf: -------------------------------------------------------------------------------- 1 | variable "tf_remote_role_arn" { 2 | 3 | } 4 | variable "cert_remote_role_arn" { 5 | 6 | } 7 | 8 | variable "environment_name" { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /terraform/stacks/managedaccount/versions.tf: -------------------------------------------------------------------------------- 1 | ../main/versions.tf -------------------------------------------------------------------------------- /terraform/stacks/regionalmasterbosh/buckets.tf: -------------------------------------------------------------------------------- 1 | module "bosh_blobstore_bucket" { 2 | source = "../../modules/s3_bucket/encrypted_bucket" 3 | bucket = var.blobstore_bucket_name 4 | aws_partition = data.aws_partition.current.partition 5 | force_destroy = "true" 6 | } 7 | 8 | module "bosh_release_bucket" { 9 | source = "../../modules/s3_bucket/encrypted_bucket" 10 | bucket = var.bosh_release_bucket 11 | aws_partition = data.aws_partition.current.partition 12 | versioning = "true" 13 | force_destroy = "true" 14 | } 15 | 16 | module "log_bucket" { 17 | source = "../../modules/log_bucket" 18 | aws_partition = data.aws_partition.current.partition 19 | log_bucket_name = var.log_bucket_name 20 | aws_region = data.aws_region.current.name 21 | } 22 | -------------------------------------------------------------------------------- /terraform/stacks/regionalmasterbosh/nessus_elb.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb_target_group" "nessus_target" { 2 | name = "${var.stack_description}-nessus" 3 | port = 8834 4 | protocol = "HTTPS" 5 | vpc_id = module.stack.vpc_id 6 | 7 | health_check { 8 | protocol = "HTTPS" 9 | healthy_threshold = 2 10 | interval = 61 11 | timeout = 60 12 | unhealthy_threshold = 3 13 | matcher = 200 14 | } 15 | } 16 | 17 | resource "aws_lb_listener_rule" "nessus_listener_rule" { 18 | listener_arn = aws_lb_listener.main.arn 19 | 20 | action { 21 | type = "forward" 22 | target_group_arn = aws_lb_target_group.nessus_target.arn 23 | } 24 | 25 | condition { 26 | host_header { 27 | values = var.nessus_hosts 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /terraform/stacks/regionalmasterbosh/read_only_access_restrictions.tf: -------------------------------------------------------------------------------- 1 | resource "aws_iam_policy" "read_only_access_restrictions" { 2 | name = "ReadOnlyAccessRestrictions" 3 | description = "Use in combination with Amazon managed ReadOnlyAccess policy." 4 | 5 | policy = < /dev/null 2>&1 || { 4 | echo "Aborted. Please install terraform by following https://www.terraform.io/intro/getting-started/install.html" 1>&2 5 | exit 1 6 | } 7 | 8 | path="$(dirname "$0")" 9 | dirs=$(find "${path}/terraform/stacks" -mindepth 1 -maxdepth 1 -type d) 10 | status=0 11 | 12 | TERRAFORM="${TERRAFORM_BIN:-terraform}" 13 | 14 | for dir in $dirs; do 15 | pushd "${dir}" || return 16 | echo "Validating terraform directory $dir" 17 | AWS_DEFAULT_REGION=us-gov-west-1 ${TERRAFORM} init -backend=false 18 | AWS_DEFAULT_REGION=us-gov-west-1 ${TERRAFORM} validate || status=1 19 | popd || return 20 | done 21 | 22 | exit ${status} 23 | -------------------------------------------------------------------------------- /validating_locally.md: -------------------------------------------------------------------------------- 1 | ## Validating `terraform plan` locally (work in progress) 2 | 3 | * Locally clone git@github.com:18F/cg-pipeline-tasks.git; you'll need `cg-pipeline-tasks/terraform-apply.sh` 4 | * This terraform setup won't use your AWS profile, so export your AWS secret 5 | key and access key (e.g. w/ 6 | https://github.com/pburkholder/Dotfiles/blob/master/bin/aws_emit) 7 | * Set up a temp directory and get the env vars from, say, the tooling pipeline: 8 | 9 | ```sh 10 | export TF_STACK=$(pwd) 11 | mkdir tmp/ 12 | cd tmp/ 13 | 14 | # set env vars from pipeline as `export key=value` for plan parameters 15 | eval "$(fly -t fr get-pipeline -p terraform-provision -j | jq -r '.| .jobs[] | select(.name=="plan-bootstrap-tooling") | .plan[1].params | to_entries[] | "export " + .key + "=" + .value')" 16 | 17 | # export your AWS vars, then run: 18 | /your/path/to/cg-pipeline-tasks/terraform-apply.sh 19 | 20 | # clean up: 21 | cd .. & rm -rf tmp/ 22 | ``` 23 | --------------------------------------------------------------------------------