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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +64 -61
- data/README.md +11 -16
- data/lib/generators/rails_template18f/active_storage/active_storage_generator.rb +7 -6
- data/lib/generators/rails_template18f/circleci/circleci_generator.rb +28 -27
- data/lib/generators/rails_template18f/circleci/templates/Dockerfile.ci.tt +0 -1
- data/lib/generators/rails_template18f/circleci/templates/circleci/config.yml.tt +162 -163
- data/lib/generators/rails_template18f/cloud_gov_config/templates/app/models/cloud_gov_config.rb +9 -1
- data/lib/generators/rails_template18f/github_actions/github_actions_generator.rb +31 -30
- data/lib/generators/rails_template18f/github_actions/templates/github/actions/compile-assets/action.yml +50 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/actions/setup-project/action.yml.tt +4 -8
- data/lib/generators/rails_template18f/github_actions/templates/github/dependabot.yml.tt +2 -4
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-production.yml +74 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml +74 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/owasp-daily-scan.yml.tt +10 -1
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/owasp-scan.yml.tt +1 -1
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/pa11y.yml.tt +2 -2
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-production.yml +49 -4
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-staging.yml +49 -4
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/validate-ssp.yml +2 -2
- data/lib/generators/rails_template18f/gitlab_ci/gitlab_ci_generator.rb +147 -0
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/node.yml.tt +11 -0
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/rails.yml +75 -0
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/ruby.yml +7 -0
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/terraform.yml +28 -0
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab-ci.yml.tt +212 -0
- data/lib/generators/rails_template18f/i18n_js/i18n_js_generator.rb +2 -2
- data/lib/generators/rails_template18f/i18n_js/templates/app/javascript/{i18n.js → i18n/index.js} +1 -1
- data/lib/generators/rails_template18f/i18n_js/templates/config/i18n-js.yml +1 -1
- data/lib/generators/rails_template18f/newrelic/newrelic_generator.rb +4 -2
- data/lib/generators/rails_template18f/public_egress/public_egress_generator.rb +71 -55
- data/lib/generators/rails_template18f/sidekiq/sidekiq_generator.rb +8 -17
- data/lib/generators/rails_template18f/terraform/templates/full_bootstrap/imports.tf.tftpl +25 -0
- data/lib/generators/rails_template18f/terraform/templates/full_bootstrap/main.tf.tt +159 -0
- data/lib/generators/rails_template18f/terraform/templates/sandbox_bootstrap/imports.tf.tftpl +10 -0
- data/lib/generators/rails_template18f/terraform/templates/sandbox_bootstrap/main.tf.tt +117 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/README.md.tt +69 -95
- data/lib/generators/rails_template18f/terraform/templates/terraform/app.tf.tt +57 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/apply.sh +15 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/templates/backend_config.tftpl +8 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/templates/bot_secrets.tftpl +5 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/users.auto.tfvars +5 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/main.tf.tt +117 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/production.tfvars.tt +13 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/providers.tf.tt +18 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/staging.tfvars.tt +8 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/terraform.sh.tt +95 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/variables.tf.tt +98 -0
- data/lib/generators/rails_template18f/terraform/terraform_generator.rb +12 -4
- data/lib/rails_template18f/generators/cloud_gov_options.rb +9 -6
- data/lib/rails_template18f/generators/cloud_gov_parsing.rb +7 -7
- data/lib/rails_template18f/generators.rb +0 -1
- data/lib/rails_template18f/version.rb +1 -1
- data/rails-template-18f.gemspec +4 -4
- data/railsrc +4 -2
- data/railsrc-hotwire +4 -2
- data/template.rb +80 -82
- data/templates/README.md.tt +21 -8
- data/templates/app/assets/stylesheets/uswds-settings.scss +3 -2
- data/templates/app/views/application/_header.html.erb +1 -1
- data/templates/app/views/application/_usa_banner.html.erb +3 -3
- data/templates/bin/ops/create_service_account.sh.tt +20 -11
- data/templates/bin/ops/destroy_service_account.sh.tt +3 -3
- data/templates/browserslistrc +1 -2
- data/templates/doc/compliance/TODO.md +1 -4
- data/templates/{pa11yci.js → pa11yci.js.tt} +5 -0
- metadata +36 -35
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-production.yml.tt +0 -50
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml.tt +0 -50
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/import.sh +0 -13
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/main.tf.tt +0 -22
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/providers.tf +0 -16
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/run.sh.tt +0 -40
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/teardown_creds.sh.tt +0 -5
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/variables.tf +0 -2
- data/lib/generators/rails_template18f/terraform/templates/terraform/production/main.tf.tt +0 -90
- data/lib/generators/rails_template18f/terraform/templates/terraform/production/providers.tf +0 -23
- data/lib/generators/rails_template18f/terraform/templates/terraform/production/variables.tf +0 -2
- data/lib/generators/rails_template18f/terraform/templates/terraform/staging/main.tf.tt +0 -70
- data/lib/generators/rails_template18f/terraform/templates/terraform/staging/providers.tf +0 -23
- data/lib/generators/rails_template18f/terraform/templates/terraform/staging/variables.tf +0 -2
- data/lib/rails_template18f/generators/pipeline_options.rb +0 -18
- data/templates/app/assets/images/uswds.js +0 -6
- data/templates/config/deployment/production.yml +0 -3
- data/templates/config/deployment/staging.yml +0 -3
- 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
|
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
|
-
|
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
|
-
|
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
|
-
###
|
23
|
+
### Initial project setup
|
34
24
|
|
35
|
-
These steps
|
25
|
+
These steps only need to be run once per project.
|
36
26
|
|
37
|
-
1.
|
38
|
-
1.
|
39
|
-
1.
|
40
|
-
1.
|
41
|
-
1.
|
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 `./
|
49
|
-
1.
|
41
|
+
1. Run `./apply.sh` and verify the plan before entering `yes`
|
42
|
+
1. Commit any changes to `imports.tf`
|
50
43
|
|
51
|
-
|
44
|
+
## Set up a sandbox environment or review app
|
52
45
|
|
53
|
-
|
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
|
-
|
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
|
-
|
51
|
+
### Steps:
|
72
52
|
|
73
|
-
1. `
|
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.
|
56
|
+
1. Run terraform plan with:
|
76
57
|
```bash
|
77
|
-
|
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
|
-
|
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
|
93
|
-
terraform plan
|
63
|
+
./terraform.sh -e <%= terraform_manage_spaces? ? "sandbox-<NAME>" : "staging" %> -c apply
|
94
64
|
```
|
95
65
|
|
96
|
-
1.
|
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
|
-
|
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
|
-
|
110
|
-
|- main.tf
|
111
|
-
|-
|
112
|
-
|-
|
113
|
-
|-
|
114
|
-
|-
|
115
|
-
|-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
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
|
123
|
-
- `
|
124
|
-
- `
|
125
|
-
- `
|
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
|
-
- `
|
129
|
-
- `
|
130
|
-
- `
|
131
|
-
- `
|
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,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
|
+
]
|