rails_template_18f 1.3.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +64 -61
  5. data/README.md +11 -16
  6. data/lib/generators/rails_template18f/active_storage/active_storage_generator.rb +7 -6
  7. data/lib/generators/rails_template18f/circleci/circleci_generator.rb +28 -27
  8. data/lib/generators/rails_template18f/circleci/templates/Dockerfile.ci.tt +0 -1
  9. data/lib/generators/rails_template18f/circleci/templates/circleci/config.yml.tt +162 -163
  10. data/lib/generators/rails_template18f/cloud_gov_config/templates/app/models/cloud_gov_config.rb +9 -1
  11. data/lib/generators/rails_template18f/github_actions/github_actions_generator.rb +31 -30
  12. data/lib/generators/rails_template18f/github_actions/templates/github/actions/compile-assets/action.yml +50 -0
  13. data/lib/generators/rails_template18f/github_actions/templates/github/actions/setup-project/action.yml.tt +4 -8
  14. data/lib/generators/rails_template18f/github_actions/templates/github/dependabot.yml.tt +2 -4
  15. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-production.yml +74 -0
  16. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml +74 -0
  17. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/owasp-daily-scan.yml.tt +10 -1
  18. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/owasp-scan.yml.tt +1 -1
  19. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/pa11y.yml.tt +2 -2
  20. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-production.yml +49 -4
  21. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-staging.yml +49 -4
  22. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/validate-ssp.yml +2 -2
  23. data/lib/generators/rails_template18f/gitlab_ci/gitlab_ci_generator.rb +147 -0
  24. data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/node.yml.tt +11 -0
  25. data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/rails.yml +75 -0
  26. data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/ruby.yml +7 -0
  27. data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/terraform.yml +28 -0
  28. data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab-ci.yml.tt +212 -0
  29. data/lib/generators/rails_template18f/i18n_js/i18n_js_generator.rb +2 -2
  30. data/lib/generators/rails_template18f/i18n_js/templates/app/javascript/{i18n.js → i18n/index.js} +1 -1
  31. data/lib/generators/rails_template18f/i18n_js/templates/config/i18n-js.yml +1 -1
  32. data/lib/generators/rails_template18f/newrelic/newrelic_generator.rb +4 -2
  33. data/lib/generators/rails_template18f/public_egress/public_egress_generator.rb +71 -55
  34. data/lib/generators/rails_template18f/sidekiq/sidekiq_generator.rb +8 -17
  35. data/lib/generators/rails_template18f/terraform/templates/full_bootstrap/imports.tf.tftpl +25 -0
  36. data/lib/generators/rails_template18f/terraform/templates/full_bootstrap/main.tf.tt +159 -0
  37. data/lib/generators/rails_template18f/terraform/templates/sandbox_bootstrap/imports.tf.tftpl +10 -0
  38. data/lib/generators/rails_template18f/terraform/templates/sandbox_bootstrap/main.tf.tt +117 -0
  39. data/lib/generators/rails_template18f/terraform/templates/terraform/README.md.tt +69 -95
  40. data/lib/generators/rails_template18f/terraform/templates/terraform/app.tf.tt +57 -0
  41. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/apply.sh +15 -0
  42. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/templates/backend_config.tftpl +8 -0
  43. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/templates/bot_secrets.tftpl +5 -0
  44. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/users.auto.tfvars +5 -0
  45. data/lib/generators/rails_template18f/terraform/templates/terraform/main.tf.tt +117 -0
  46. data/lib/generators/rails_template18f/terraform/templates/terraform/production.tfvars.tt +13 -0
  47. data/lib/generators/rails_template18f/terraform/templates/terraform/providers.tf.tt +18 -0
  48. data/lib/generators/rails_template18f/terraform/templates/terraform/staging.tfvars.tt +8 -0
  49. data/lib/generators/rails_template18f/terraform/templates/terraform/terraform.sh.tt +95 -0
  50. data/lib/generators/rails_template18f/terraform/templates/terraform/variables.tf.tt +98 -0
  51. data/lib/generators/rails_template18f/terraform/terraform_generator.rb +12 -4
  52. data/lib/rails_template18f/generators/cloud_gov_options.rb +9 -6
  53. data/lib/rails_template18f/generators/cloud_gov_parsing.rb +7 -7
  54. data/lib/rails_template18f/generators.rb +0 -1
  55. data/lib/rails_template18f/version.rb +1 -1
  56. data/rails-template-18f.gemspec +4 -4
  57. data/railsrc +4 -2
  58. data/railsrc-hotwire +4 -2
  59. data/template.rb +80 -82
  60. data/templates/README.md.tt +21 -8
  61. data/templates/app/assets/stylesheets/uswds-settings.scss +3 -2
  62. data/templates/app/views/application/_header.html.erb +1 -1
  63. data/templates/app/views/application/_usa_banner.html.erb +3 -3
  64. data/templates/bin/ops/create_service_account.sh.tt +20 -11
  65. data/templates/bin/ops/destroy_service_account.sh.tt +3 -3
  66. data/templates/browserslistrc +1 -2
  67. data/templates/doc/compliance/TODO.md +1 -4
  68. data/templates/{pa11yci.js → pa11yci.js.tt} +5 -0
  69. metadata +36 -35
  70. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-production.yml.tt +0 -50
  71. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml.tt +0 -50
  72. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/import.sh +0 -13
  73. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/main.tf.tt +0 -22
  74. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/providers.tf +0 -16
  75. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/run.sh.tt +0 -40
  76. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/teardown_creds.sh.tt +0 -5
  77. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/variables.tf +0 -2
  78. data/lib/generators/rails_template18f/terraform/templates/terraform/production/main.tf.tt +0 -90
  79. data/lib/generators/rails_template18f/terraform/templates/terraform/production/providers.tf +0 -23
  80. data/lib/generators/rails_template18f/terraform/templates/terraform/production/variables.tf +0 -2
  81. data/lib/generators/rails_template18f/terraform/templates/terraform/staging/main.tf.tt +0 -70
  82. data/lib/generators/rails_template18f/terraform/templates/terraform/staging/providers.tf +0 -23
  83. data/lib/generators/rails_template18f/terraform/templates/terraform/staging/variables.tf +0 -2
  84. data/lib/rails_template18f/generators/pipeline_options.rb +0 -18
  85. data/templates/app/assets/images/uswds.js +0 -6
  86. data/templates/config/deployment/production.yml +0 -3
  87. data/templates/config/deployment/staging.yml +0 -3
  88. data/templates/manifest.yml.tt +0 -17
@@ -0,0 +1,117 @@
1
+ terraform {
2
+ required_version = "~> 1.10"
3
+ required_providers {
4
+ cloudfoundry = {
5
+ source = "cloudfoundry/cloudfoundry"
6
+ version = "1.2.0"
7
+ }
8
+ }
9
+ }
10
+ # empty config will let terraform borrow cf-cli's auth
11
+ provider "cloudfoundry" {}
12
+
13
+ variable "create_bot_secrets_file" {
14
+ type = bool
15
+ default = false
16
+ description = "Flag whether to create secrets.cicd.tfvars file"
17
+ }
18
+
19
+ locals {
20
+ org_name = "<%= cloud_gov_organization %>"
21
+ cf_space_name = "<%= cloud_gov_staging_space %>"
22
+ }
23
+
24
+ data "cloudfoundry_org" "org" {
25
+ name = local.org_name
26
+ }
27
+ data "cloudfoundry_space" "space" {
28
+ name = local.cf_space_name
29
+ org = data.cloudfoundry_org.org.id
30
+ }
31
+
32
+ module "s3" {
33
+ source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v2.3.0"
34
+
35
+ cf_space_id = data.cloudfoundry_space.space.id
36
+ name = "<%= app_name %>-terraform-state"
37
+ s3_plan_name = "basic-sandbox"
38
+ }
39
+
40
+ data "cloudfoundry_service_plans" "cg_service_account" {
41
+ name = "space-deployer"
42
+ service_offering_name = "cloud-gov-service-account"
43
+ }
44
+ locals {
45
+ sa_service_name = "<%= app_name %>-cicd-deployer"
46
+ sa_key_name = "cicd-deployer-access-key"
47
+ sa_bot_credentials = jsondecode(data.cloudfoundry_service_credential_binding.runner_sa_key.credential_bindings.0.credential_binding).credentials
48
+ }
49
+ resource "cloudfoundry_service_instance" "runner_service_account" {
50
+ name = local.sa_service_name
51
+ type = "managed"
52
+ space = data.cloudfoundry_space.space.id
53
+ service_plan = data.cloudfoundry_service_plans.cg_service_account.service_plans.0.id
54
+ }
55
+ resource "cloudfoundry_service_credential_binding" "runner_sa_key" {
56
+ name = local.sa_key_name
57
+ service_instance = cloudfoundry_service_instance.runner_service_account.id
58
+ type = "key"
59
+ }
60
+ data "cloudfoundry_service_credential_binding" "runner_sa_key" {
61
+ name = local.sa_key_name
62
+ service_instance = cloudfoundry_service_instance.runner_service_account.id
63
+ depends_on = [cloudfoundry_service_credential_binding.runner_sa_key]
64
+ }
65
+
66
+ locals {
67
+ bucket_creds_key_name = "backend-state-bucket-creds"
68
+ }
69
+ resource "cloudfoundry_service_credential_binding" "bucket_creds" {
70
+ name = local.bucket_creds_key_name
71
+ service_instance = module.s3.bucket_id
72
+ type = "key"
73
+ }
74
+ data "cloudfoundry_service_credential_binding" "bucket_creds" {
75
+ name = local.bucket_creds_key_name
76
+ service_instance = module.s3.bucket_id
77
+ depends_on = [cloudfoundry_service_credential_binding.bucket_creds]
78
+ }
79
+
80
+ locals {
81
+ import_map = {
82
+ "module.s3.cloudfoundry_service_instance.bucket" = module.s3.bucket_id
83
+ "cloudfoundry_service_credential_binding.bucket_creds" = cloudfoundry_service_credential_binding.bucket_creds.id
84
+ "cloudfoundry_service_instance.runner_service_account" = cloudfoundry_service_instance.runner_service_account.id
85
+ "cloudfoundry_service_credential_binding.runner_sa_key" = cloudfoundry_service_credential_binding.runner_sa_key.id
86
+ }
87
+
88
+ recreate_state_template = templatefile("${path.module}/templates/imports.tf.tftpl", { import_map = local.import_map })
89
+ }
90
+ resource "local_file" "recreate_script" {
91
+ content = local.recreate_state_template
92
+ filename = "${path.module}/imports.tf"
93
+ file_permission = "0644"
94
+ }
95
+
96
+ locals {
97
+ bucket_creds = jsondecode(data.cloudfoundry_service_credential_binding.bucket_creds.credential_bindings.0.credential_binding).credentials
98
+ backend_config = templatefile("${path.module}/templates/backend_config.tftpl", { creds = local.bucket_creds })
99
+ }
100
+ resource "local_sensitive_file" "bucket_creds" {
101
+ content = local.backend_config
102
+ filename = "${path.module}/../secrets.backend.tfvars"
103
+ file_permission = "0600"
104
+ }
105
+
106
+ resource "local_sensitive_file" "bot_secrets_file" {
107
+ count = (var.create_bot_secrets_file ? 1 : 0)
108
+ filename = "${path.module}/../secrets.cicd.tfvars"
109
+ file_permission = "0600"
110
+
111
+ content = templatefile("${path.module}/templates/bot_secrets.tftpl", {
112
+ service_name = local.sa_service_name,
113
+ key_name = local.sa_key_name,
114
+ username = local.sa_bot_credentials.username,
115
+ password = local.sa_bot_credentials.password
116
+ })
117
+ }
@@ -1,133 +1,107 @@
1
1
  # Terraform
2
2
 
3
- This directory holds the terraform modules for maintaining your complete persistent infrastructure.
3
+ This directory holds the terraform module for maintaining the system infrastructure and deploying the application.
4
+ <% unless terraform_manage_spaces? %>
5
+ ## READ ME FIRST
4
6
 
5
- Prerequisite: install the `jq` JSON processor: `brew bundle` or `brew install jq`
7
+ Due to users not having `OrgManager` permission in the `sandbox-gsa` organization, this version of the terraform module
8
+ is very limited.
6
9
 
7
- ## Initial project setup
8
-
9
- These steps only need to be run once per project.
10
-
11
- 1. Manually [bootstrap the state storage bucket](#bootstrapping-the-state-storage-s3-buckets-for-the-first-time) within the `bootstrap` directory
12
- 1. Setup CI/CD Pipeline to run Terraform
13
- 1. Copy bootstrap credentials to your CI/CD secrets using the instructions in the base README
14
- 1. Create a cloud.gov SpaceDeployer by following the instructions under `SpaceDeployers`
15
- 1. Copy SpaceDeployer credentials to your CI/CD secrets using the instructions in the base README
16
- 1. Manually Running Terraform
17
- 1. Follow instructions under `Set up a new environment` to create your infrastructure
18
-
19
- ## Initial developer setup
20
-
21
- These steps should be run for any developer that needs to start running terraform or who just moved to a new machine.
22
-
23
- They are not necessary for the developer who runs the [initial project setup](#initial-project-setup)
24
-
25
- 1. Import the existing bootstrap resources to your local state with `./import.sh`
26
- 1. Follow instructions under [Use bootstrap credentials](#use-bootstrap-credentials)
10
+ When you are ready to move the application to a non-sandbox cloud.gov organization, please re-run the terraform generator with…
27
11
 
12
+ ```bash
13
+ bin/rails generate rails_template18f:terraform --cg-org=<ORG_NAME> --cg-staging=<STAGING_SPACE_NAME> --cg-prod=<PRODUCTION_SPACE_NAME>
14
+ ```
28
15
 
16
+ …to take full advantage of the generator, and then re-run your CI generator of choice to add production terraform plan and apply steps to your workflow.
17
+ <% end %>
29
18
  ## Terraform State Credentials
30
19
 
31
- The `bootstrap` module is used to create an s3 bucket for later terraform runs to store their state in.
20
+ The `bootstrap` module is used to create an s3 bucket for later terraform runs to store their state in as well as
21
+ create credentials files so developers can use that s3 bucket to create their own sandbox environments.
32
22
 
33
- ### Bootstrapping the state storage s3 buckets for the first time
23
+ ### Initial project setup
34
24
 
35
- These steps are run once per project.
25
+ These steps only need to be run once per project.
36
26
 
37
- 1. Run `./run.sh init`
38
- 1. Run `./run.sh apply` to set up the bucket and retrieve credentials
39
- 1. Follow instructions under [Use bootstrap credentials](#use-bootstrap-credentials)
40
- 1. Ensure that `import.sh` includes a line and correct IDs for any resources created
41
- 1. Run `./teardown_creds.sh` to remove the space deployer account used to create the s3 bucket
27
+ 1. `cd bootstrap`<% if terraform_manage_spaces? %>
28
+ 1. Add any users who should have access to the terraform state bucket to `users.auto.tfvars`<% end %>
29
+ 1. Run `./apply.sh -var create_bot_secrets_file=true`
30
+ 1. Add `imports.tf` to git and commit the changes
31
+ 1. Setup your CI/CD Pipeline to run terraform and deploy your staging and production environments
32
+ 1. Copy backend credentials from `/terraform/secrets.backend.tfvars` to your CI/CD secrets using the instructions in the base README
33
+ 1. Copy the cf_user and cf_password credentials from `/terraform/secrets.cicd.tfvars` to your CI/CD secrets using the instructions in the base README
34
+ 1. Delete the two secrets files
42
35
 
43
36
  ### To make changes to the bootstrap module
44
37
 
45
- *This should not be necessary in most cases*
38
+ *This should not be necessary in most cases<% if terraform_manage_spaces? %>, other than adding or removing users who should have access to the state bucket in `bootstrap/users.auto.tfvars`<% end %>*
46
39
 
47
40
  1. Make your changes
48
- 1. Run `./run.sh plan` to verify the changes are what you expect
49
- 1. Continue from step 2 of the [boostrapping instructions](#bootstrapping-the-state-storage-s3-buckets-for-the-first-time)
41
+ 1. Run `./apply.sh` and verify the plan before entering `yes`
42
+ 1. Commit any changes to `imports.tf`
50
43
 
51
- ### Use bootstrap credentials
44
+ ## Set up a sandbox environment or review app
52
45
 
53
- 1. Add the following to `~/.aws/credentials`
54
- ```
55
- [<%= app_name %>-terraform-backend]
56
- aws_access_key_id = <AWS_ACCESS_KEY_ID from run.sh output>
57
- aws_secret_access_key = <AWS_SECRET_ACCESS_KEY from run.sh output>
58
- ```
59
-
60
- 1. Copy `BUCKET` from `run.sh` output to the backend block of `staging/providers.tf` and `production/providers.tf`
61
-
62
- ## SpaceDeployers
63
-
64
- A [SpaceDeployer](https://cloud.gov/docs/services/cloud-gov-service-account/) account is required to run terraform or
65
- deploy the application from the CI/CD pipeline. Create a new account by running:
66
-
67
- `../bin/ops/create_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME> -m`
46
+ ### Pre-requisites:
68
47
 
69
- ## Set up a new environment manually
48
+ 1. Someone on the team has run the [Initial project setup](#initial-project-setup) steps and `imports.tf` is up-to-date on your branch.
49
+ <% if terraform_manage_spaces? %>1. You are included in the list of users in `bootstrap/users.auto.tfvars` and `bootstrap/imports.tf`<% end %>
70
50
 
71
- The below steps rely on you first configuring access to the Terraform state in s3 as described in [initial project setup](#initial-project-setup) or [initial developer setup](#initial-developer-setup).
51
+ ### Steps:
72
52
 
73
- 1. `cd` to the environment you are working in
53
+ <% if terraform_manage_spaces? %>1. Create a new `sandbox-<NAME>.tfvars` file to hold variable values for your environment. A good starting point is copying `staging.tfvars` and editing it with your values
54
+ 1. Add a `cf_user = "your.email@agency.gov"` line to the `sandbox-<NAME>.tfvars` file<% end %>
74
55
 
75
- 1. Set up a SpaceDeployer and save the credentials in a file named `secrets.auto.tfvars`
56
+ 1. Run terraform plan with:
76
57
  ```bash
77
- # create a space deployer service instance that can log in with just a username and password
78
- # the value of < SPACE_NAME > should be `staging` or `prod` depending on where you are working
79
- # the value for < ACCOUNT_NAME > can be anything, although we recommend
80
- # something that communicates the purpose of the deployer
81
- # for example: circleci-deployer for the credentials CircleCI uses to
82
- # deploy the application or <your_name>-terraform for credentials to run terraform manually
83
- ../../bin/ops/create_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME> -m > secrets.auto.tfvars
58
+ ./terraform.sh -e <%= terraform_manage_spaces? ? "sandbox-<NAME>" : "staging" %>
84
59
  ```
85
60
 
86
- The script will output the `username` (as `cf_user`) and `password` (as `cf_password`) for your `<ACCOUNT_NAME>`. Read more in the [cloud.gov service account documentation](https://cloud.gov/docs/services/cloud-gov-service-account/).
87
-
88
- The easiest way to use this script locally is to redirect the output directly to the `secrets.auto.tfvars` file it needs to be used in
89
-
90
- 1. Run terraform from your new environment directory with
61
+ 1. Apply changes with:
91
62
  ```bash
92
- terraform init -backend-config="profile=<%= app_name %>-terraform-backend"
93
- terraform plan
63
+ ./terraform.sh -e <%= terraform_manage_spaces? ? "sandbox-<NAME>" : "staging" %> -c apply
94
64
  ```
95
65
 
96
- 1. Apply changes with `terraform apply`.
97
-
98
- 1. Remove the space deployer service instance if it doesn't need to be used again, such as when manually running terraform plan before letting CI/CD apply the changes.
66
+ 1. <%= terraform_manage_spaces? ? "Optional: tear down the sandbox if" : "Destroy the app when" %> it does not need to be used anymore
99
67
  ```bash
100
- # <SPACE_NAME> and <ACCOUNT_NAME> have the same values as used above.
101
- ../../bin/ops/destroy_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME>
68
+ ./terraform.sh -e <%= terraform_manage_spaces? ? "sandbox-<NAME>" : "staging" %> -c destroy
102
69
  ```
103
70
 
104
71
  ## Structure
105
72
 
106
- Each environment has its own module.
107
-
108
73
  ```
109
- - bootstrap/
110
- |- main.tf
111
- |- providers.tf
112
- |- variables.tf
113
- |- run.sh
114
- |- teardown_creds.sh
115
- |- import.sh
116
- - <env>/
117
- |- main.tf
118
- |- providers.tf
119
- |- variables.tf
74
+ |- bootstrap/
75
+ | |- main.tf
76
+ | |- apply.sh
77
+ | |- imports.tf (automatically generated)
78
+ | |- users.auto.tfvars
79
+ | |- terraform.tfstate(.backup) (automatically generated)
80
+ | |- templates/
81
+ | |- backend_config.tftpl
82
+ | |- bot_secrets.tftpl
83
+ | |- imports.tf.tftpl
84
+ |- dist/
85
+ | |- src.zip (automatically generated)
86
+ |- README.md
87
+ |- app.tf
88
+ |- main.tf
89
+ |- providers.tf
90
+ |- terraform.sh
91
+ |- variables.tf
92
+ |- <env>.tfvars
120
93
  ```
121
94
 
122
- In the environment-specific modules:
123
- - `providers.tf` lists the required providers
124
- - `main.tf` calls the shared Terraform code, but this is also a place where you can add any other services, resources, etc, which you would like to set up for that environment
125
- - `variables.tf` lists the variables that will be needed, either to pass through to the child module or for use in this module
95
+ In the root module:
96
+ - `<env>.tfvars` is where to set variable values for the given environment name
97
+ - `terraform.sh` Helper script to setup terraform to point to the correct state file, create a service account to run the root module, and apply the root module.
98
+ - `app.tf` defines the application resource and configuration
99
+ - `main.tf` defines the persistent infrastructure
100
+ - `providers.tf` lists the required providers and shell backend config
101
+ - `variables.tf` lists the variables that will be needed
126
102
 
127
103
  In the bootstrap module:
128
- - `providers.tf` lists the required providers
129
- - `main.tf` sets up s3 bucket to be shared across all environments. It lives in `prod` to communicate that it should not be deleted
130
- - `variables.tf` lists the variables that will be needed. Most values are hard-coded in this module
131
- - `run.sh` Helper script to set up a space deployer and run terraform. The terraform action (`init`/`show`/`plan`/`apply`/`destroy`) is passed as an argument
132
- - `teardown_creds.sh` Helper script to remove the space deployer setup as part of `run.sh`
133
- - `import.sh` Helper script to create a new local state file when new developers need to access the state file
104
+ - `main.tf` sets up a management space, an s3 bucket to store terraform state files, and an initial SpaceDeployer for the system
105
+ - `apply.sh` Helper script to either recreate the state locally or call `terraform apply` Any arguments are passed through to the `apply` call
106
+ - `imports.tf` import blocks to create a new local state file when new developers need to access the state file. This file is automatically generated by calling `./apply.sh` and should be checked into git on any changes
107
+ - `users.auto.tfvars` this file defines the list of cloud.gov accounts that should have access to the terraform state bucket
@@ -0,0 +1,57 @@
1
+ data "archive_file" "src" {
2
+ type = "zip"
3
+ source_dir = "${path.module}/.."
4
+ output_path = "${path.module}/dist/src.zip"
5
+ excludes = [
6
+ ".git*",
7
+ ".circleci/*",
8
+ ".bundle/*",
9
+ "node_modules/*",
10
+ "tmp/**/*",
11
+ "terraform/*",
12
+ "log/*",
13
+ "doc/*"
14
+ ]
15
+ }
16
+
17
+ resource "cloudfoundry_app" "app" {
18
+ name = "${local.app_name}-${var.env}"
19
+ space_name = var.cf_space_name
20
+ org_name = local.cf_org_name
21
+
22
+ path = data.archive_file.src.output_path
23
+ source_code_hash = data.archive_file.src.output_base64sha256
24
+ buildpacks = ["ruby_buildpack"]
25
+ strategy = "rolling"
26
+
27
+ environment = {
28
+ RAILS_ENV = var.env
29
+ RAILS_MASTER_KEY = var.rails_master_key
30
+ RAILS_LOG_TO_STDOUT = "true"
31
+ RAILS_SERVE_STATIC_FILES = "true"
32
+ }
33
+
34
+ processes = [
35
+ {
36
+ type = "web"
37
+ instances = var.web_instances
38
+ memory = var.web_memory
39
+ health_check_http_endpoint = "/up"
40
+ health_check_type = "http"
41
+ command = "./bin/rake cf:on_first_instance db:migrate && exec env HTTP_PORT=$PORT ./bin/thrust ./bin/rails server"
42
+ }
43
+ ]
44
+
45
+ service_bindings = [
46
+ <% if has_active_job? %> { service_instance = "${local.app_name}-redis-${var.env}" },<% end %>
47
+ <% if has_active_storage? %> { service_instance = "${local.app_name}-s3-${var.env}" },<% end %>
48
+ { service_instance = "${local.app_name}-rds-${var.env}" }
49
+ ]
50
+
51
+ depends_on = [
52
+ <% if has_active_job? %> module.redis,<% end %>
53
+ <% if has_active_storage? %> module.s3,<% end %>
54
+ <% if terraform_manage_spaces? %> module.app_space,<% end %>
55
+ module.database
56
+ ]
57
+ }
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if ! command -v terraform &> /dev/null
4
+ then
5
+ echo "terraform must be installed before running this script"
6
+ exit 1
7
+ fi
8
+
9
+ set -e
10
+
11
+ # ensure we're logged in via cli
12
+ cf spaces &> /dev/null || cf login -a api.fr.cloud.gov --sso
13
+
14
+ terraform init
15
+ terraform apply "$@"
@@ -0,0 +1,8 @@
1
+ # remove this file after initializing your terraform
2
+ # you can always regenerate it by running ./apply.sh
3
+ # within the bootstrap module
4
+
5
+ bucket = "${creds.bucket}"
6
+ region = "${creds.region}"
7
+ access_key = "${creds.access_key_id}"
8
+ secret_key = "${creds.secret_access_key}"
@@ -0,0 +1,5 @@
1
+ # Generated via bootstrap module. Remove this file when finished
2
+ # credentials for service "${service_name}"/"${key_name}"
3
+
4
+ cf_user = "${username}"
5
+ cf_password = "${password}"
@@ -0,0 +1,5 @@
1
+ terraform_users = [
2
+ # add your terraform_users list here: example values:
3
+ # "team.member@gsa.gov",
4
+ # "cf_user-guid-value-for-space-developer-service-account",
5
+ ]
@@ -0,0 +1,117 @@
1
+ locals {
2
+ cf_org_name = "<%= cloud_gov_organization %>"
3
+ app_name = "<%= app_name %>"
4
+ space_deployers = setunion([var.cf_user], var.space_deployers)
5
+ }
6
+ <% if terraform_manage_spaces? %>
7
+ module "app_space" {
8
+ source = "github.com/gsa-tts/terraform-cloudgov//cg_space?ref=v2.3.0"
9
+
10
+ cf_org_name = local.cf_org_name
11
+ cf_space_name = var.cf_space_name
12
+ allow_ssh = var.allow_space_ssh
13
+ deployers = local.space_deployers
14
+ developers = var.space_developers
15
+ auditors = var.space_auditors
16
+ security_group_names = ["trusted_local_networks_egress"]
17
+ }
18
+ <% else %>
19
+ data "cloudfoundry_org" "org" {
20
+ name = local.cf_org_name
21
+ }
22
+ data "cloudfoundry_space" "app_space" {
23
+ name = var.cf_space_name
24
+ org = data.cloudfoundry_org.org.id
25
+ }
26
+ data "cloudfoundry_security_group" "trusted_egress_security_group" {
27
+ name = "trusted_local_networks_egress"
28
+ }
29
+ resource "cloudfoundry_security_group_space_bindings" "trusted_egress_binding" {
30
+ security_group = data.cloudfoundry_security_group.trusted_egress_security_group.id
31
+ running_spaces = [data.cloudfoundry_space.app_space.id]
32
+ }
33
+ <% end %>
34
+ module "database" {
35
+ source = "github.com/gsa-tts/terraform-cloudgov//database?ref=v2.3.0"
36
+
37
+ cf_space_id = <% if terraform_manage_spaces? %>module.app_space.space_id<% else %>data.cloudfoundry_space.app_space.id<% end %>
38
+ name = "${local.app_name}-rds-${var.env}"
39
+ rds_plan_name = var.rds_plan_name<% if terraform_manage_spaces? %>
40
+ # depends_on line is required only for initial creation and destruction. It can be commented out for updates if you see unwanted cascading effects
41
+ depends_on = [module.app_space]<% end %>
42
+ }
43
+ <% if has_active_job? %>
44
+ module "redis" {
45
+ source = "github.com/gsa-tts/terraform-cloudgov//redis?ref=v2.3.0"
46
+
47
+ cf_space_id = <% if terraform_manage_spaces? %>module.app_space.space_id<% else %>data.cloudfoundry_space.app_space.id<% end %>
48
+ name = "${local.app_name}-redis-${var.env}"
49
+ redis_plan_name = var.redis_plan_name<% if terraform_manage_spaces? %>
50
+ # depends_on line is required only for initial creation and destruction. It can be commented out for updates if you see unwanted cascading effects
51
+ depends_on = [module.app_space]<% end %>
52
+ }
53
+ <% end %><% if has_active_storage? %>
54
+ module "s3" {
55
+ source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v2.3.0"
56
+
57
+ cf_space_id = <% if terraform_manage_spaces? %>module.app_space.space_id<% else %>data.cloudfoundry_space.app_space.id<% end %>
58
+ name = "${local.app_name}-s3-${var.env}"
59
+ s3_plan_name = var.s3_plan_name<% if terraform_manage_spaces? %>
60
+ # depends_on line is required only for initial creation and destruction. It can be commented out for updates if you see unwanted cascading effects
61
+ depends_on = [module.app_space]<% end %>
62
+ }
63
+
64
+ module "clamav" {
65
+ source = "github.com/gsa-tts/terraform-cloudgov//clamav?ref=v2.3.0"
66
+
67
+ cf_org_name = local.cf_org_name
68
+ cf_space_name = var.cf_space_name
69
+ name = "${local.app_name}-clamapi-${var.env}"
70
+ clamav_image = "ghcr.io/gsa-tts/clamav-rest/clamav:latest"
71
+ max_file_size = "30M"<% if terraform_manage_spaces? %>
72
+ # depends_on line is required only for initial creation and destruction. It can be commented out for updates if you see unwanted cascading effects
73
+ depends_on = [module.app_space]<% end %>
74
+ }
75
+
76
+ resource "cloudfoundry_network_policy" "clamav_routing" {
77
+ policies = [{
78
+ source_app = cloudfoundry_app.app.id
79
+ destination_app = module.clamav.app_id
80
+ port = "61443"
81
+ }]
82
+ }
83
+ <% end %>
84
+ ###########################################################################<% if terraform_manage_spaces? %>
85
+ # Before setting var.custom_domain_name, ensure the ACME challenge record has been created:
86
+ # See https://cloud.gov/docs/services/external-domain-service/#how-to-create-an-instance-of-this-service<% else %>
87
+ # Before setting var.custom_domain_name, perform the following steps:
88
+ # 1) Domain must be manually created by an OrgManager:
89
+ # cf create-domain var.cf_org_name var.domain_name
90
+ # 2) ACME challenge record must be created.
91
+ # See https://cloud.gov/docs/services/external-domain-service/#how-to-create-an-instance-of-this-service<% end %>
92
+ ###########################################################################
93
+ module "domain" {
94
+ count = (var.custom_domain_name == null ? 0 : 1)
95
+ source = "github.com/gsa-tts/terraform-cloudgov//domain?ref=v2.3.0"
96
+
97
+ cf_org_name = local.cf_org_name
98
+ cf_space = <% if terraform_manage_spaces? %>module.app_space.space<% else %>data.cloudfoundry_space.app_space<% end %>
99
+ cdn_plan_name = "domain"
100
+ domain_name = var.custom_domain_name
101
+ create_domain = <%= terraform_manage_spaces? ? "true" : "false" %>
102
+ app_ids = [cloudfoundry_app.app.id]
103
+ host_name = var.host_name<% if terraform_manage_spaces? %>
104
+ # depends_on line is required only for initial creation and destruction. It can be commented out for updates if you see unwanted cascading effects
105
+ depends_on = [module.app_space]<% end %>
106
+ }
107
+ module "app_route" {
108
+ count = (var.custom_domain_name == null ? 1 : 0)
109
+ source = "github.com/gsa-tts/terraform-cloudgov//app_route?ref=v2.3.0"
110
+
111
+ cf_org_name = local.cf_org_name
112
+ cf_space_name = var.cf_space_name
113
+ app_ids = [cloudfoundry_app.app.id]
114
+ hostname = coalesce(var.host_name, "${local.app_name}-${var.env}")<% if terraform_manage_spaces? %>
115
+ # depends_on line is required only for initial creation and destruction. It can be commented out for updates if you see unwanted cascading effects
116
+ depends_on = [module.app_space]<% end %>
117
+ }
@@ -0,0 +1,13 @@
1
+ cf_space_name = "<%= cloud_gov_production_space %>"
2
+ env = "production"
3
+ rds_plan_name = "TKTK-production-rds-plan"
4
+ custom_domain_name = null
5
+ host_name = null
6
+ web_instances = 2
7
+ web_memory = "512M"
8
+ <% if has_active_storage? %>s3_plan_name = "basic"<% end %>
9
+ <% if has_active_job? %>redis_plan_name = "TKTK-production-redis-plan"<% end %>
10
+ <% if has_active_job? %>worker_memory = "512M"<% end %>
11
+ space_auditors = [
12
+ # enter cloud.gov usernames that should have access to audit logs
13
+ ]
@@ -0,0 +1,18 @@
1
+ terraform {
2
+ required_version = "~> 1.10"
3
+ required_providers {
4
+ cloudfoundry = {
5
+ source = "cloudfoundry/cloudfoundry"
6
+ version = "1.5.0"
7
+ }
8
+ }
9
+
10
+ backend "s3" {
11
+ encrypt = true
12
+ use_lockfile = true
13
+ use_fips_endpoint = true
14
+ region = "us-gov-west-1"
15
+ }
16
+ }
17
+
18
+ provider "cloudfoundry" {}
@@ -0,0 +1,8 @@
1
+ cf_space_name = "<%= cloud_gov_staging_space %>"
2
+ env = "staging"
3
+ allow_space_ssh = true
4
+ # host_name must be unique across cloud.gov, default is "<%= app_name %>-${var.env}"
5
+ host_name = null
6
+ space_developers = [
7
+ # enter developer emails that should have ssh access to staging
8
+ ]