rails_template_18f 2.0.0 → 2.2.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 +13 -0
- data/Gemfile.lock +9 -7
- data/lib/generators/rails_template18f/active_storage/active_storage_generator.rb +4 -3
- data/lib/generators/rails_template18f/auditree/auditree_generator.rb +36 -6
- data/lib/generators/rails_template18f/auditree/templates/gitlab/auditree.yml.tt +48 -0
- data/lib/generators/rails_template18f/circleci/templates/circleci/config.yml.tt +12 -2
- data/lib/generators/rails_template18f/cloud_gov_config/cloud_gov_config_generator.rb +0 -8
- data/lib/generators/rails_template18f/cloud_gov_config/templates/app/models/cloud_gov_config.rb +6 -7
- data/lib/generators/rails_template18f/cloud_gov_config/templates/spec/models/cloud_gov_config_spec.rb +13 -19
- data/lib/generators/rails_template18f/github_actions/github_actions_generator.rb +0 -4
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-production.yml +3 -1
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml +3 -1
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-production.yml +3 -1
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-staging.yml +3 -1
- data/lib/generators/rails_template18f/gitlab_ci/gitlab_ci_generator.rb +138 -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 +33 -0
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab-ci.yml.tt +213 -0
- data/lib/generators/rails_template18f/oscal/oscal_generator.rb +15 -1
- data/lib/generators/rails_template18f/oscal/templates/bin/trestle.tt +10 -1
- data/lib/generators/rails_template18f/oscal/templates/gitlab/trestle.yml.tt +29 -0
- data/lib/generators/rails_template18f/public_egress/public_egress_generator.rb +16 -32
- data/lib/generators/rails_template18f/sidekiq/templates/config/initializers/redis.rb +1 -1
- data/lib/generators/rails_template18f/terraform/templates/gitlab_bootstrap/apply.sh +25 -0
- data/lib/generators/rails_template18f/terraform/templates/gitlab_bootstrap/main.tf.tt +98 -0
- data/lib/generators/rails_template18f/terraform/templates/gitlab_bootstrap/setup_shadowenv.sh +59 -0
- data/lib/generators/rails_template18f/terraform/templates/s3_bootstrap/common/templates/backend_config.tftpl +6 -0
- data/lib/generators/rails_template18f/terraform/templates/s3_bootstrap/common/templates/bot_secrets.tftpl +5 -0
- data/lib/generators/rails_template18f/terraform/templates/s3_bootstrap/common/users.auto.tfvars +5 -0
- data/lib/generators/rails_template18f/terraform/templates/{full_bootstrap → s3_bootstrap/full}/main.tf.tt +4 -11
- data/lib/generators/rails_template18f/terraform/templates/{sandbox_bootstrap → s3_bootstrap/sandbox}/main.tf.tt +3 -3
- data/lib/generators/rails_template18f/terraform/templates/terraform/.shadowenv.d/.gitignore +3 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/README.md.tt +38 -36
- data/lib/generators/rails_template18f/terraform/templates/terraform/app.tf.tt +1 -6
- data/lib/generators/rails_template18f/terraform/templates/terraform/main.tf.tt +30 -19
- data/lib/generators/rails_template18f/terraform/templates/terraform/production.tfvars.tt +3 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/providers.tf.tt +4 -24
- data/lib/generators/rails_template18f/terraform/templates/terraform/staging.tfvars.tt +5 -5
- data/lib/generators/rails_template18f/terraform/templates/terraform/terraform.sh.tt +40 -55
- data/lib/generators/rails_template18f/terraform/templates/terraform/variables.tf.tt +11 -12
- data/lib/generators/rails_template18f/terraform/terraform_generator.rb +78 -6
- data/lib/rails_template18f/version.rb +1 -1
- data/template.rb +50 -25
- data/templates/{pa11yci.js → pa11yci.js.tt} +5 -0
- metadata +28 -20
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/templates/backend_config.tftpl +0 -8
- data/lib/generators/rails_template18f/terraform/templates/terraform/sandbox_bot/main.tf +0 -74
- data/lib/generators/rails_template18f/terraform/templates/terraform/sandbox_bot/run.sh +0 -17
- /data/lib/generators/rails_template18f/{github_actions → oscal}/templates/github/workflows/assemble-ssp.yml.tt +0 -0
- /data/lib/generators/rails_template18f/{github_actions → oscal}/templates/github/workflows/validate-ssp.yml +0 -0
- /data/lib/generators/rails_template18f/terraform/templates/{terraform/bootstrap/templates → gitlab_bootstrap}/bot_secrets.tftpl +0 -0
- /data/lib/generators/rails_template18f/terraform/templates/{terraform/bootstrap → gitlab_bootstrap}/users.auto.tfvars +0 -0
- /data/lib/generators/rails_template18f/terraform/templates/{terraform/bootstrap → s3_bootstrap/common}/apply.sh +0 -0
- /data/lib/generators/rails_template18f/terraform/templates/{full_bootstrap → s3_bootstrap/full}/imports.tf.tftpl +0 -0
- /data/lib/generators/rails_template18f/terraform/templates/{sandbox_bootstrap → s3_bootstrap/sandbox}/imports.tf.tftpl +0 -0
@@ -3,7 +3,7 @@ terraform {
|
|
3
3
|
required_providers {
|
4
4
|
cloudfoundry = {
|
5
5
|
source = "cloudfoundry/cloudfoundry"
|
6
|
-
version = "1.
|
6
|
+
version = "~> 1.7"
|
7
7
|
}
|
8
8
|
}
|
9
9
|
}
|
@@ -30,7 +30,7 @@ data "cloudfoundry_space" "space" {
|
|
30
30
|
}
|
31
31
|
|
32
32
|
module "s3" {
|
33
|
-
source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v2.
|
33
|
+
source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v2.3.0"
|
34
34
|
|
35
35
|
cf_space_id = data.cloudfoundry_space.space.id
|
36
36
|
name = "<%= app_name %>-terraform-state"
|
@@ -99,7 +99,7 @@ locals {
|
|
99
99
|
}
|
100
100
|
resource "local_sensitive_file" "bucket_creds" {
|
101
101
|
content = local.backend_config
|
102
|
-
filename = "${path.module}
|
102
|
+
filename = "${path.module}/../.shadowenv.d/500_tf_backend_secrets.lisp"
|
103
103
|
file_permission = "0600"
|
104
104
|
}
|
105
105
|
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# Terraform
|
2
2
|
|
3
3
|
This directory holds the terraform module for maintaining the system infrastructure and deploying the application.
|
4
|
-
|
5
4
|
<% unless terraform_manage_spaces? %>
|
6
5
|
## READ ME FIRST
|
7
6
|
|
@@ -11,48 +10,57 @@ is very limited.
|
|
11
10
|
When you are ready to move the application to a non-sandbox cloud.gov organization, please re-run the terraform generator with…
|
12
11
|
|
13
12
|
```bash
|
14
|
-
bin/rails generate rails_template18f:terraform --cg-org=<ORG_NAME> --cg-staging=<STAGING_SPACE_NAME> --cg-prod=<PRODUCTION_SPACE_NAME>
|
13
|
+
bin/rails generate rails_template18f:terraform --cg-org=<ORG_NAME> --cg-staging=<STAGING_SPACE_NAME> --cg-prod=<PRODUCTION_SPACE_NAME> --backend=<%= backend_unless_local %>
|
15
14
|
```
|
16
15
|
|
17
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.
|
18
17
|
<% end %>
|
18
|
+
<% unless use_local_backend? %>## Terraform State Credentials
|
19
19
|
|
20
|
-
|
20
|
+
The `bootstrap` module is used to create resources that must be created by an individual developers credentials before automation can be run:
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
* service account and credentials to provide to the CI/CD pipeline to perform future updates<% unless use_gitlab_backend? %>
|
23
|
+
* an s3 bucket for later terraform runs to store their state in<% end %>
|
24
24
|
|
25
|
-
### Initial project setup
|
25
|
+
### Initial <%= use_gitlab_backend? ? "CI/CD pipeline" : "project" %> setup
|
26
26
|
|
27
27
|
These steps only need to be run once per project.
|
28
28
|
|
29
|
-
1. `cd bootstrap`<% if
|
30
|
-
1.
|
29
|
+
1. `cd bootstrap`<% if use_gitlab_backend? %>
|
30
|
+
1. Run `./setup_shadowenv.sh`<% end %><% if terraform_manage_spaces? %>
|
31
|
+
1. Add any users who should have access to the management space to `users.auto.tfvars`<% end %><% if use_gitlab_backend? %>
|
32
|
+
1. Run `./apply.sh`<% else %>
|
31
33
|
1. Run `./apply.sh -var create_bot_secrets_file=true`
|
32
|
-
1. Add `imports.tf` to git and commit the changes
|
33
|
-
1. Setup your CI/CD Pipeline to run terraform and deploy your staging and production environments
|
34
|
-
1. Copy backend credentials from `/terraform/
|
35
|
-
1. Copy the cf_user and cf_password credentials from
|
36
|
-
1. Delete
|
34
|
+
1. Add `imports.tf` to git and commit the changes<% end %>
|
35
|
+
1. Setup your CI/CD Pipeline to run terraform and deploy your staging and production environments<% unless use_gitlab_backend? %>
|
36
|
+
1. Copy backend credentials from `/terraform/.shadowenv.d/500_tf_backend_secrets.lisp` to your CI/CD secrets using the instructions in the base README<% end %>
|
37
|
+
1. Copy the `cf_user` and `cf_password` credentials from `secrets.cicd.tfvars` to your CI/CD secrets using the instructions in the base README
|
38
|
+
1. Delete `secrets.cicd.tfvars`
|
39
|
+
1. Delete `.shadowenv.d/500_tf_backend_secrets.lisp` if you won't be running terraform locally
|
37
40
|
|
38
41
|
### To make changes to the bootstrap module
|
39
42
|
|
40
|
-
*This should not be necessary in most cases<% if terraform_manage_spaces? %>, other than adding or removing users who should have access to the
|
43
|
+
*This should not be necessary in most cases<% if terraform_manage_spaces? %>, other than adding or removing users who should have access to the mgmt space in `bootstrap/users.auto.tfvars`<% end %>*
|
41
44
|
|
42
45
|
1. Make your changes
|
43
|
-
1. Run `./apply.sh` and verify the plan before entering `yes
|
44
|
-
1. Commit any changes to `imports.tf
|
46
|
+
1. Run `./apply.sh` and verify the plan before entering `yes`<% unless use_gitlab_backend? %>
|
47
|
+
1. Commit any changes to `imports.tf`<% end %><% end %>
|
45
48
|
|
46
|
-
|
49
|
+
<% if use_local_backend? %>
|
50
|
+
## Deploy the App
|
51
|
+
<% else %>
|
52
|
+
## Set up a sandbox environment or review app<% unless use_gitlab_backend? %>
|
47
53
|
|
48
54
|
### Pre-requisites:
|
49
55
|
|
50
56
|
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.
|
51
|
-
<% if terraform_manage_spaces? %>1. You are included in the list of users in `bootstrap/users.auto.tfvars` and `bootstrap/imports.tf`<% end %>
|
57
|
+
<% if terraform_manage_spaces? %>1. You are included in the list of users in `bootstrap/users.auto.tfvars` and `bootstrap/imports.tf`<% end %><% end %><% end %>
|
52
58
|
|
53
59
|
### Steps:
|
54
|
-
|
55
|
-
|
60
|
+
<% if use_gitlab_backend? %>
|
61
|
+
1. Run `./bootstrap/setup_shadowenv.sh`<% end %>
|
62
|
+
<% 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
|
63
|
+
1. Add a `cf_user = "your.email@gsa.gov"` line to the `sandbox-<NAME>.tfvars` file<% end %>
|
56
64
|
|
57
65
|
1. Run terraform plan with:
|
58
66
|
```bash
|
@@ -71,22 +79,19 @@ These steps only need to be run once per project.
|
|
71
79
|
|
72
80
|
## Structure
|
73
81
|
|
74
|
-
|
82
|
+
```<% unless use_local_backend? %>
|
75
83
|
|- bootstrap/
|
76
84
|
| |- main.tf
|
77
85
|
| |- apply.sh
|
86
|
+
| |- users.auto.tfvars<% if use_gitlab_backend? %>
|
87
|
+
| |- setup_shadowenv.sh
|
88
|
+
| |- bot_secrets.tftpl<% else %>
|
78
89
|
| |- imports.tf (automatically generated)
|
79
|
-
| |- users.auto.tfvars
|
80
90
|
| |- terraform.tfstate(.backup) (automatically generated)
|
81
91
|
| |- templates/
|
82
92
|
| |- backend_config.tftpl
|
83
93
|
| |- bot_secrets.tftpl
|
84
|
-
| |- imports.tf.tftpl<%
|
85
|
-
|- sandbox_bot/
|
86
|
-
| |- main.tf
|
87
|
-
| |- run.sh
|
88
|
-
| |- <sandbox_name>/ (automatically generated)
|
89
|
-
| |- terraform.tfstate(.backup) (automatically generated)<% end %>
|
94
|
+
| |- imports.tf.tftpl<% end %><% end %>
|
90
95
|
|- dist/
|
91
96
|
| |- src.zip (automatically generated)
|
92
97
|
|- README.md
|
@@ -106,12 +111,9 @@ In the root module:
|
|
106
111
|
- `providers.tf` lists the required providers and shell backend config
|
107
112
|
- `variables.tf` lists the variables that will be needed
|
108
113
|
|
109
|
-
In the bootstrap module:
|
114
|
+
<% unless use_local_backend? %>In the bootstrap module:
|
110
115
|
- `main.tf` sets up a management space, an s3 bucket to store terraform state files, and an initial SpaceDeployer for the system
|
111
|
-
- `apply.sh` Helper script to
|
112
|
-
- `
|
113
|
-
- `
|
114
|
-
|
115
|
-
In the sandbox_bot module:
|
116
|
-
- `main.tf` sets up a cloud.gov SpaceDeployer to manage the sandbox environment and outputs its credentials into the main module `secrets.auto.tfvars`
|
117
|
-
- `run.sh` Helper script to set up a separate local state file for each sandbox name. In normal use this will only ever be called by `./terraform.sh`
|
116
|
+
- `apply.sh` Helper script to setup terraform and call `terraform apply`. Any arguments are passed through to the `apply` call
|
117
|
+
- `users.auto.tfvars` this file defines the list of cloud.gov accounts that should have access to the management space<% if use_gitlab_backend? %>
|
118
|
+
- `setup_shadowenv.sh` helper script to set terraform backend values using the gitlab http backend in shadowenv<% else %>
|
119
|
+
- `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<% end %><% end %>
|
@@ -14,11 +14,6 @@ data "archive_file" "src" {
|
|
14
14
|
]
|
15
15
|
}
|
16
16
|
|
17
|
-
locals {
|
18
|
-
host_name = coalesce(var.host_name, "${local.app_name}-${var.env}")
|
19
|
-
domain = coalesce(var.custom_domain_name, "app.cloud.gov")
|
20
|
-
}
|
21
|
-
|
22
17
|
resource "cloudfoundry_app" "app" {
|
23
18
|
name = "${local.app_name}-${var.env}"
|
24
19
|
space_name = var.cf_space_name
|
@@ -28,7 +23,7 @@ resource "cloudfoundry_app" "app" {
|
|
28
23
|
source_code_hash = data.archive_file.src.output_base64sha256
|
29
24
|
buildpacks = ["ruby_buildpack"]
|
30
25
|
strategy = "rolling"
|
31
|
-
|
26
|
+
enable_ssh = var.allow_ssh
|
32
27
|
|
33
28
|
environment = {
|
34
29
|
RAILS_ENV = var.env
|
@@ -1,18 +1,18 @@
|
|
1
1
|
locals {
|
2
2
|
cf_org_name = "<%= cloud_gov_organization %>"
|
3
|
-
app_name = "<%= app_name %>"
|
4
|
-
space_deployers = setunion([var.cf_user], var.space_deployers)
|
3
|
+
app_name = "<%= app_name.tr("_", "-") %>"<% if terraform_manage_spaces? %>
|
4
|
+
space_deployers = setunion([var.cf_user], var.space_deployers)<% end %>
|
5
5
|
}
|
6
|
-
|
7
6
|
<% if terraform_manage_spaces? %>
|
8
7
|
module "app_space" {
|
9
|
-
source = "github.com/gsa-tts/terraform-cloudgov//cg_space?ref=v2.
|
8
|
+
source = "github.com/gsa-tts/terraform-cloudgov//cg_space?ref=v2.3.0"
|
10
9
|
|
11
10
|
cf_org_name = local.cf_org_name
|
12
11
|
cf_space_name = var.cf_space_name
|
13
|
-
allow_ssh = var.
|
12
|
+
allow_ssh = var.allow_ssh
|
14
13
|
deployers = local.space_deployers
|
15
14
|
developers = var.space_developers
|
15
|
+
auditors = var.space_auditors
|
16
16
|
security_group_names = ["trusted_local_networks_egress"]
|
17
17
|
}
|
18
18
|
<% else %>
|
@@ -31,9 +31,8 @@ resource "cloudfoundry_security_group_space_bindings" "trusted_egress_binding" {
|
|
31
31
|
running_spaces = [data.cloudfoundry_space.app_space.id]
|
32
32
|
}
|
33
33
|
<% end %>
|
34
|
-
|
35
34
|
module "database" {
|
36
|
-
source = "github.com/gsa-tts/terraform-cloudgov//database?ref=v2.
|
35
|
+
source = "github.com/gsa-tts/terraform-cloudgov//database?ref=v2.3.0"
|
37
36
|
|
38
37
|
cf_space_id = <% if terraform_manage_spaces? %>module.app_space.space_id<% else %>data.cloudfoundry_space.app_space.id<% end %>
|
39
38
|
name = "${local.app_name}-rds-${var.env}"
|
@@ -43,7 +42,7 @@ module "database" {
|
|
43
42
|
}
|
44
43
|
<% if has_active_job? %>
|
45
44
|
module "redis" {
|
46
|
-
source = "github.com/gsa-tts/terraform-cloudgov//redis?ref=v2.
|
45
|
+
source = "github.com/gsa-tts/terraform-cloudgov//redis?ref=v2.3.0"
|
47
46
|
|
48
47
|
cf_space_id = <% if terraform_manage_spaces? %>module.app_space.space_id<% else %>data.cloudfoundry_space.app_space.id<% end %>
|
49
48
|
name = "${local.app_name}-redis-${var.env}"
|
@@ -51,10 +50,9 @@ module "redis" {
|
|
51
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
|
52
51
|
depends_on = [module.app_space]<% end %>
|
53
52
|
}
|
54
|
-
<% end %>
|
55
|
-
<% if has_active_storage? %>
|
53
|
+
<% end %><% if has_active_storage? %>
|
56
54
|
module "s3" {
|
57
|
-
source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v2.
|
55
|
+
source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v2.3.0"
|
58
56
|
|
59
57
|
cf_space_id = <% if terraform_manage_spaces? %>module.app_space.space_id<% else %>data.cloudfoundry_space.app_space.id<% end %>
|
60
58
|
name = "${local.app_name}-s3-${var.env}"
|
@@ -64,7 +62,7 @@ module "s3" {
|
|
64
62
|
}
|
65
63
|
|
66
64
|
module "clamav" {
|
67
|
-
source = "github.com/gsa-tts/terraform-cloudgov//clamav?ref=v2.
|
65
|
+
source = "github.com/gsa-tts/terraform-cloudgov//clamav?ref=v2.3.0"
|
68
66
|
|
69
67
|
cf_org_name = local.cf_org_name
|
70
68
|
cf_space_name = var.cf_space_name
|
@@ -76,31 +74,44 @@ module "clamav" {
|
|
76
74
|
}
|
77
75
|
|
78
76
|
resource "cloudfoundry_network_policy" "clamav_routing" {
|
79
|
-
|
80
|
-
policy {
|
77
|
+
policies = [{
|
81
78
|
source_app = cloudfoundry_app.app.id
|
82
79
|
destination_app = module.clamav.app_id
|
83
80
|
port = "61443"
|
84
|
-
}
|
81
|
+
}]
|
85
82
|
}
|
86
83
|
<% end %>
|
87
|
-
|
88
|
-
|
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 %>
|
89
87
|
# Before setting var.custom_domain_name, perform the following steps:
|
90
88
|
# 1) Domain must be manually created by an OrgManager:
|
91
89
|
# cf create-domain var.cf_org_name var.domain_name
|
92
90
|
# 2) ACME challenge record must be created.
|
93
|
-
# See https://cloud.gov/docs/services/external-domain-service/#how-to-create-an-instance-of-this-service
|
91
|
+
# See https://cloud.gov/docs/services/external-domain-service/#how-to-create-an-instance-of-this-service<% end %>
|
94
92
|
###########################################################################
|
95
93
|
module "domain" {
|
96
94
|
count = (var.custom_domain_name == null ? 0 : 1)
|
97
|
-
source = "github.com/gsa-tts/terraform-cloudgov//domain?ref=v2.
|
95
|
+
source = "github.com/gsa-tts/terraform-cloudgov//domain?ref=v2.3.0"
|
98
96
|
|
99
97
|
cf_org_name = local.cf_org_name
|
100
98
|
cf_space = <% if terraform_manage_spaces? %>module.app_space.space<% else %>data.cloudfoundry_space.app_space<% end %>
|
101
99
|
cdn_plan_name = "domain"
|
102
100
|
domain_name = var.custom_domain_name
|
101
|
+
create_domain = <%= terraform_manage_spaces? ? "true" : "false" %>
|
102
|
+
app_ids = [cloudfoundry_app.app.id]
|
103
103
|
host_name = var.host_name<% if terraform_manage_spaces? %>
|
104
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
105
|
depends_on = [module.app_space]<% end %>
|
106
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
|
+
}
|
@@ -8,3 +8,6 @@ web_memory = "512M"
|
|
8
8
|
<% if has_active_storage? %>s3_plan_name = "basic"<% end %>
|
9
9
|
<% if has_active_job? %>redis_plan_name = "TKTK-production-redis-plan"<% end %>
|
10
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
|
+
]
|
@@ -1,32 +1,12 @@
|
|
1
1
|
terraform {
|
2
2
|
required_version = "~> 1.10"
|
3
|
-
required_providers {
|
4
|
-
cloudfoundry-community = {
|
5
|
-
source = "cloudfoundry-community/cloudfoundry"
|
6
|
-
version = "0.53.1"
|
7
|
-
}<% end %>
|
3
|
+
required_providers {
|
8
4
|
cloudfoundry = {
|
9
5
|
source = "cloudfoundry/cloudfoundry"
|
10
|
-
version = "1.
|
6
|
+
version = "~> 1.7"
|
11
7
|
}
|
12
8
|
}
|
13
9
|
|
14
|
-
|
15
|
-
encrypt = true
|
16
|
-
use_lockfile = true
|
17
|
-
region = "us-gov-west-1"
|
18
|
-
}
|
19
|
-
}
|
10
|
+
<%= backend_block %>}
|
20
11
|
|
21
|
-
provider "cloudfoundry" {
|
22
|
-
api_url = "https://api.fr.cloud.gov"
|
23
|
-
user = var.cf_user
|
24
|
-
password = var.cf_password
|
25
|
-
}
|
26
|
-
<% if has_active_storage? %>
|
27
|
-
provider "cloudfoundry-community" {
|
28
|
-
api_url = "https://api.fr.cloud.gov"
|
29
|
-
user = var.cf_user
|
30
|
-
password = var.cf_password
|
31
|
-
}
|
32
|
-
<% end %>
|
12
|
+
provider "cloudfoundry" {}
|
@@ -1,8 +1,8 @@
|
|
1
|
-
cf_space_name
|
2
|
-
env
|
3
|
-
|
1
|
+
cf_space_name = "<%= cloud_gov_staging_space %>"
|
2
|
+
env = "staging"
|
3
|
+
allow_ssh = true
|
4
4
|
# host_name must be unique across cloud.gov, default is "<%= app_name %>-${var.env}"
|
5
|
-
host_name = null
|
5
|
+
host_name = null<% if terraform_manage_spaces? %>
|
6
6
|
space_developers = [
|
7
7
|
# enter developer emails that should have ssh access to staging
|
8
|
-
]
|
8
|
+
]<% end %>
|
@@ -20,8 +20,8 @@ Options:
|
|
20
20
|
"
|
21
21
|
|
22
22
|
|
23
|
-
rmk
|
24
|
-
env=""
|
23
|
+
rmk=$(cat $rmk_file || echo -n "")
|
24
|
+
env="<% unless terraform_manage_spaces? %>staging<% end %>"
|
25
25
|
force=""
|
26
26
|
args_to_shift=0
|
27
27
|
|
@@ -54,7 +54,21 @@ done
|
|
54
54
|
shift $args_to_shift
|
55
55
|
if [[ "$1" = "--" ]]; then
|
56
56
|
shift 1
|
57
|
-
fi
|
57
|
+
fi<% if use_gitlab_backend? %>
|
58
|
+
|
59
|
+
if [ -z "$GITLAB_PROJECT_ID" ] || [ -z "$GITLAB_HOSTNAME" ]; then
|
60
|
+
echo "GITLAB_PROJECT_ID or GITLAB_HOSTNAME have not been set. Running bootstrap/setup_shadowenv.sh first"
|
61
|
+
(cd bootstrap && ./setup_shadowenv.sh)
|
62
|
+
eval "$(shadowenv hook)"
|
63
|
+
fi<% elsif use_s3_backend? %>
|
64
|
+
|
65
|
+
if [[ ! -f .shadowenv.d/500_tf_backend_secrets.lisp ]]; then
|
66
|
+
echo "=============================================================================================================="
|
67
|
+
echo "= Recreating backend config file. It is fine if this step wants to delete any local_sensitive_file resources"
|
68
|
+
echo "=============================================================================================================="
|
69
|
+
(cd bootstrap && ./apply.sh $force)
|
70
|
+
shadowenv trust && eval "$(shadowenv hook)"
|
71
|
+
fi<% end %>
|
58
72
|
|
59
73
|
if [[ -z "$env" ]]; then
|
60
74
|
echo "-e <ENV_NAME> is required"
|
@@ -70,66 +84,37 @@ fi
|
|
70
84
|
# ensure we're logged in via cli
|
71
85
|
cf spaces &> /dev/null || cf login -a api.fr.cloud.gov --sso
|
72
86
|
|
73
|
-
tfm_needs_init=true
|
87
|
+
tfm_needs_init=true<% if use_gitlab_backend? %>
|
88
|
+
tf_state_address="https://$GITLAB_HOSTNAME/api/v4/projects/$GITLAB_PROJECT_ID/terraform/state/$env"
|
74
89
|
if [[ -f .terraform/terraform.tfstate ]]; then
|
75
|
-
|
76
|
-
if [[ "$
|
90
|
+
backend_state_address=$(cat .terraform/terraform.tfstate | jq -r ".backend.config.address")
|
91
|
+
if [[ "$backend_state_address" = "$tf_state_address" ]]; then
|
77
92
|
tfm_needs_init=false
|
78
93
|
fi
|
79
|
-
fi
|
80
|
-
|
81
|
-
|
82
|
-
if [[
|
83
|
-
|
84
|
-
echo "= Recreating backend config file. It is fine if this step wants to delete any local_sensitive_file resources"
|
85
|
-
echo "=============================================================================================================="
|
86
|
-
(cd bootstrap && ./apply.sh $force)
|
94
|
+
fi<% elsif use_s3_backend? %>
|
95
|
+
if [[ -f .terraform/terraform.tfstate ]]; then
|
96
|
+
backend_state_env=$(cat .terraform/terraform.tfstate | jq -r ".backend.config.key" | cut -d '.' -f3)
|
97
|
+
if [[ "$backend_state_env" = "$env" ]]; then
|
98
|
+
tfm_needs_init=false
|
87
99
|
fi
|
88
|
-
terraform init -backend-config=secrets.backend.tfvars -backend-config="key=terraform.tfstate.$env" -reconfigure
|
89
|
-
fi
|
90
|
-
|
91
|
-
echo "=============================================================================================================="
|
92
|
-
echo "= Creating a bot deployer for $env"
|
93
|
-
echo "=============================================================================================================="
|
94
|
-
<% if terraform_manage_spaces? %>
|
95
|
-
if [[ "$env" = "staging" ]] || [[ "$env" = "production" ]]; then
|
96
|
-
(cd bootstrap && ./apply.sh -var create_bot_secrets_file=true $force)
|
97
100
|
else
|
98
|
-
|
99
|
-
|
100
|
-
<% else %>
|
101
|
-
if [[
|
102
|
-
|
103
|
-
fi
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
101
|
+
echo "Sleeping for 10 seconds to avoid a bucket creation race condition"
|
102
|
+
sleep 10
|
103
|
+
fi<% else %>
|
104
|
+
if [[ -f .terraform.lock.hcl ]]; then
|
105
|
+
tfm_needs_init=false
|
106
|
+
fi<% end %>
|
107
|
+
|
108
|
+
if [[ $tfm_needs_init = true ]]; then<% if use_gitlab_backend? %>
|
109
|
+
terraform init -reconfigure \
|
110
|
+
-backend-config="address=$tf_state_address" \
|
111
|
+
-backend-config="lock_address=$tf_state_address/lock" \
|
112
|
+
-backend-config="unlock_address=$tf_state_address/lock"<% elsif use_s3_backend? %>
|
113
|
+
terraform init -backend-config="bucket=$S3_BUCKET_NAME" -backend-config="key=terraform.tfstate.$env" -reconfigure<% else %>
|
114
|
+
terraform init<% end %>
|
108
115
|
fi
|
109
116
|
|
110
117
|
echo "=============================================================================================================="
|
111
118
|
echo "= Calling $cmd $force on the application infrastructure"
|
112
119
|
echo "=============================================================================================================="
|
113
120
|
terraform "$cmd" -var-file="$env.tfvars" -var rails_master_key="$rmk" $force "$@"
|
114
|
-
|
115
|
-
<% if terraform_manage_spaces? %>
|
116
|
-
if [[ "$cmd" = "destroy" ]] && [[ "$env" != "staging" ]] && [[ "$env" != "production" ]]; then
|
117
|
-
<% else %>
|
118
|
-
if [[ "$cmd" = "destroy" ]]; then
|
119
|
-
<% end %>
|
120
|
-
if [[ -z "$force" ]]; then
|
121
|
-
read -p "Destroy the sandbox_bot user? (y/n) " confirm
|
122
|
-
if [[ "$confirm" != "y" ]]; then
|
123
|
-
exit 0
|
124
|
-
fi
|
125
|
-
fi
|
126
|
-
echo "=============================================================================================================="
|
127
|
-
echo "= Destroying the sandbox_bot user"
|
128
|
-
echo "=============================================================================================================="
|
129
|
-
<% if terraform_manage_spaces? %>
|
130
|
-
(cd sandbox_bot && ./run.sh "$env" destroy -auto-approve)
|
131
|
-
<% else %>
|
132
|
-
../bin/ops/destroy_service_account.sh -s <%= cloud_gov_staging_space %> -u terraform-deployer
|
133
|
-
rm secrets.auto.tfvars
|
134
|
-
<% end %>
|
135
|
-
fi
|
@@ -1,19 +1,14 @@
|
|
1
|
-
|
1
|
+
<% if terraform_manage_spaces? %># Deploy user settings
|
2
2
|
variable "cf_user" {
|
3
3
|
type = string
|
4
|
-
description = "The service account running the terraform"
|
4
|
+
description = "The user email or service account running the terraform"
|
5
5
|
}
|
6
|
-
|
7
|
-
type = string
|
8
|
-
sensitive = true
|
9
|
-
description = "The service account password"
|
10
|
-
}
|
11
|
-
|
6
|
+
<% end %>
|
12
7
|
# app_space settings
|
13
8
|
variable "cf_space_name" {
|
14
9
|
type = string
|
15
10
|
description = "The space name to deploy the app into"
|
16
|
-
}
|
11
|
+
}<% if terraform_manage_spaces? %>
|
17
12
|
variable "space_deployers" {
|
18
13
|
type = set(string)
|
19
14
|
default = []
|
@@ -24,10 +19,15 @@ variable "space_developers" {
|
|
24
19
|
default = []
|
25
20
|
description = "A list of users to be granted SpaceDeveloper on cf_space_name"
|
26
21
|
}
|
27
|
-
variable "
|
22
|
+
variable "space_auditors" {
|
23
|
+
type = set(string)
|
24
|
+
default = []
|
25
|
+
description = "A list of users to be granted SpaceAuditor on cf_space_name"
|
26
|
+
}<% end %>
|
27
|
+
variable "allow_ssh" {
|
28
28
|
type = bool
|
29
29
|
default = false
|
30
|
-
description = "Whether to allow ssh to
|
30
|
+
description = "Whether to allow ssh to the space and/or app"
|
31
31
|
}
|
32
32
|
|
33
33
|
# supporting services settings
|
@@ -50,7 +50,6 @@ variable "s3_plan_name" {
|
|
50
50
|
description = "The name of the s3 plan to use"
|
51
51
|
}
|
52
52
|
<% end %>
|
53
|
-
|
54
53
|
# routing settings
|
55
54
|
variable "custom_domain_name" {
|
56
55
|
type = string
|
@@ -8,6 +8,8 @@ module RailsTemplate18f
|
|
8
8
|
include Base
|
9
9
|
include CloudGovOptions
|
10
10
|
|
11
|
+
class_option :backend, default: "s3", desc: "Which terraform backend to use. Options: [s3, gitlab, local]"
|
12
|
+
|
11
13
|
desc <<~DESC
|
12
14
|
Description:
|
13
15
|
Install terraform files for cloud.gov database and s3 services
|
@@ -16,18 +18,43 @@ module RailsTemplate18f
|
|
16
18
|
def install
|
17
19
|
directory "terraform", mode: :preserve
|
18
20
|
chmod "terraform/terraform.sh", 0o755
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
end
|
22
|
+
|
23
|
+
def install_bootstrap
|
24
|
+
if use_gitlab_backend?
|
25
|
+
directory "gitlab_bootstrap", "terraform/bootstrap", mode: :preserve
|
26
|
+
elsif use_s3_backend?
|
27
|
+
directory "s3_bootstrap/common", "terraform/bootstrap", mode: :preserve
|
28
|
+
if terraform_manage_spaces?
|
29
|
+
template "s3_bootstrap/full/main.tf", "terraform/bootstrap/main.tf"
|
30
|
+
copy_file "s3_bootstrap/full/imports.tf.tftpl", "terraform/bootstrap/templates/imports.tf.tftpl"
|
31
|
+
else
|
32
|
+
template "s3_bootstrap/sandbox/main.tf", "terraform/bootstrap/main.tf"
|
33
|
+
copy_file "s3_bootstrap/sandbox/imports.tf.tftpl", "terraform/bootstrap/templates/imports.tf.tftpl"
|
34
|
+
end
|
22
35
|
else
|
23
|
-
|
24
|
-
|
36
|
+
remove_dir "terraform/.shadowenv.d"
|
37
|
+
end
|
38
|
+
unless terraform_manage_spaces?
|
25
39
|
remove_file "terraform/bootstrap/users.auto.tfvars"
|
26
|
-
remove_dir "terraform/sandbox_bot"
|
27
40
|
remove_file "terraform/production.tfvars"
|
28
41
|
end
|
29
42
|
end
|
30
43
|
|
44
|
+
def install_shadowenv
|
45
|
+
unless use_local_backend?
|
46
|
+
append_to_file "Brewfile", <<~EOB
|
47
|
+
|
48
|
+
# shadowenv for loading terraform backend secrets
|
49
|
+
brew "shadowenv"
|
50
|
+
EOB
|
51
|
+
insert_into_file "README.md", indent(<<~EOR), after: /\* Install homebrew dependencies: `brew bundle`\n/
|
52
|
+
* [shadowenv](https://shopify.github.io/shadowenv/)
|
53
|
+
* See the [quick start](https://shopify.github.io/shadowenv/getting-started/#add-to-your-shell-profile) for instructions on loading shadowenv in your shell
|
54
|
+
EOR
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
31
58
|
def ignore_files
|
32
59
|
unless skip_git?
|
33
60
|
append_to_file ".gitignore", <<~EOM
|
@@ -87,6 +114,51 @@ module RailsTemplate18f
|
|
87
114
|
done
|
88
115
|
EOM
|
89
116
|
end
|
117
|
+
|
118
|
+
def use_gitlab_backend?
|
119
|
+
backend == "gitlab"
|
120
|
+
end
|
121
|
+
|
122
|
+
def use_s3_backend?
|
123
|
+
backend == "s3"
|
124
|
+
end
|
125
|
+
|
126
|
+
def use_local_backend?
|
127
|
+
backend == "local"
|
128
|
+
end
|
129
|
+
|
130
|
+
def backend
|
131
|
+
options[:backend]
|
132
|
+
end
|
133
|
+
|
134
|
+
def backend_unless_local
|
135
|
+
if use_local_backend?
|
136
|
+
"<s3 or gitlab>"
|
137
|
+
else
|
138
|
+
backend
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def backend_block
|
143
|
+
if use_gitlab_backend?
|
144
|
+
<<EOB
|
145
|
+
backend "http" {
|
146
|
+
lock_method = "POST"
|
147
|
+
unlock_method = "DELETE"
|
148
|
+
retry_wait_min = 5
|
149
|
+
}
|
150
|
+
EOB
|
151
|
+
elsif use_s3_backend?
|
152
|
+
<<EOB
|
153
|
+
backend "s3" {
|
154
|
+
encrypt = true
|
155
|
+
use_lockfile = true
|
156
|
+
use_fips_endpoint = true
|
157
|
+
region = "us-gov-west-1"
|
158
|
+
}
|
159
|
+
EOB
|
160
|
+
end
|
161
|
+
end
|
90
162
|
end
|
91
163
|
end
|
92
164
|
end
|