rails_template_18f 2.1.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 +8 -0
- data/Gemfile.lock +5 -3
- 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/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 -15
- 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/gitlab_ci/gitlab_ci_generator.rb +0 -9
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/rails.yml +2 -2
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/terraform.yml +8 -3
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab-ci.yml.tt +2 -1
- 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 +1 -1
- 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 +2 -9
- data/lib/generators/rails_template18f/terraform/templates/{sandbox_bootstrap → s3_bootstrap/sandbox}/main.tf.tt +2 -2
- 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 -26
- data/lib/generators/rails_template18f/terraform/templates/terraform/app.tf.tt +1 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/main.tf.tt +3 -3
- data/lib/generators/rails_template18f/terraform/templates/terraform/providers.tf.tt +2 -8
- 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 -15
- data/lib/generators/rails_template18f/terraform/templates/terraform/variables.tf.tt +6 -6
- data/lib/generators/rails_template18f/terraform/terraform_generator.rb +78 -5
- data/lib/rails_template18f/version.rb +1 -1
- data/template.rb +32 -15
- metadata +21 -13
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/templates/backend_config.tftpl +0 -8
- /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
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
#
|
3
|
+
# Setup .shadowenv.d/ files for terraform configuration
|
4
|
+
|
5
|
+
set -e
|
6
|
+
|
7
|
+
# ensure we're operating with the correct relative paths
|
8
|
+
cd `dirname "$0"`
|
9
|
+
|
10
|
+
shadowenv trust && eval "$(shadowenv hook)"
|
11
|
+
|
12
|
+
ans=""
|
13
|
+
prompt_ans() {
|
14
|
+
local prompt="$1"
|
15
|
+
local default="$2"
|
16
|
+
if [ -n "$default" ]; then
|
17
|
+
prompt="$prompt (default: $default)"
|
18
|
+
fi
|
19
|
+
read -r -p "$prompt: " ans
|
20
|
+
}
|
21
|
+
|
22
|
+
prompt_ans "GitLab hostname" "${GITLAB_HOSTNAME:=gsa.gitlab-dedicated.us}"
|
23
|
+
if [ -n "$ans" ]; then
|
24
|
+
GITLAB_HOSTNAME="$ans"
|
25
|
+
fi
|
26
|
+
|
27
|
+
prompt_ans "GitLab project id" "$GITLAB_PROJECT_ID"
|
28
|
+
if [ -n "$ans" ]; then
|
29
|
+
GITLAB_PROJECT_ID="$ans"
|
30
|
+
fi
|
31
|
+
|
32
|
+
if [ ! -d ../.shadowenv.d ]; then
|
33
|
+
mkdir ../.shadowenv.d
|
34
|
+
fi
|
35
|
+
|
36
|
+
cat <<EOF > ../.shadowenv.d/100_gitlab_project.lisp
|
37
|
+
(provide "gitlab-backend-config")
|
38
|
+
(env/set "GITLAB_HOSTNAME" "$GITLAB_HOSTNAME")
|
39
|
+
(env/set "GITLAB_PROJECT_ID" "$GITLAB_PROJECT_ID")
|
40
|
+
EOF
|
41
|
+
|
42
|
+
prompt_ans "GitLab username" "$TF_HTTP_USERNAME"
|
43
|
+
if [ -n "$ans" ]; then
|
44
|
+
TF_HTTP_USERNAME=$ans
|
45
|
+
fi
|
46
|
+
if [ -z "$TF_HTTP_PASSWORD" ]; then
|
47
|
+
prompt_ans "GitLab PAT (with api scope)"
|
48
|
+
else
|
49
|
+
prompt_ans "GitLab PAT (with api scope, Leave blank to re-use existing PAT)"
|
50
|
+
fi
|
51
|
+
if [ -n "$ans" ]; then
|
52
|
+
TF_HTTP_PASSWORD=$ans
|
53
|
+
fi
|
54
|
+
|
55
|
+
cat <<EOF > ../.shadowenv.d/500_tf_backend_secrets.lisp
|
56
|
+
(provide "tf-backend-secrets")
|
57
|
+
(env/set "TF_HTTP_USERNAME" "$TF_HTTP_USERNAME")
|
58
|
+
(env/set "TF_HTTP_PASSWORD" "$TF_HTTP_PASSWORD")
|
59
|
+
EOF
|
@@ -0,0 +1,6 @@
|
|
1
|
+
(provide "terraform-backend-config")
|
2
|
+
(env/set "S3_BUCKET_NAME" "${creds.bucket}")
|
3
|
+
(env/set "AWS_ACCESS_KEY_ID" "${creds.access_key_id}")
|
4
|
+
(env/set "AWS_SECRET_ACCESS_KEY" "${creds.secret_access_key}")
|
5
|
+
; not a secret, but setting it here enables the aws cli to work when in the terraform directory
|
6
|
+
(env/set "AWS_REGION" "${creds.region}")
|
@@ -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
|
}
|
@@ -134,7 +134,7 @@ locals {
|
|
134
134
|
}
|
135
135
|
resource "local_sensitive_file" "bucket_creds" {
|
136
136
|
content = local.backend_config
|
137
|
-
filename = "${path.module}
|
137
|
+
filename = "${path.module}/../.shadowenv.d/500_tf_backend_secrets.lisp"
|
138
138
|
file_permission = "0600"
|
139
139
|
}
|
140
140
|
|
@@ -150,10 +150,3 @@ resource "local_sensitive_file" "bot_secrets_file" {
|
|
150
150
|
password = local.sa_cf_password
|
151
151
|
})
|
152
152
|
}
|
153
|
-
|
154
|
-
output "mgmt_space_id" {
|
155
|
-
value = module.mgmt_space.space_id
|
156
|
-
}
|
157
|
-
output "mgmt_org_id" {
|
158
|
-
value = data.cloudfoundry_org.org.id
|
159
|
-
}
|
@@ -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
|
}
|
@@ -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
|
|
@@ -10,48 +10,57 @@ is very limited.
|
|
10
10
|
When you are ready to move the application to a non-sandbox cloud.gov organization, please re-run the terraform generator with…
|
11
11
|
|
12
12
|
```bash
|
13
|
-
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 %>
|
14
14
|
```
|
15
15
|
|
16
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
17
|
<% end %>
|
18
|
-
|
18
|
+
<% unless use_local_backend? %>## Terraform State Credentials
|
19
19
|
|
20
|
-
The `bootstrap` module is used to create
|
21
|
-
create credentials files so developers can use that s3 bucket to create their own sandbox environments.
|
20
|
+
The `bootstrap` module is used to create resources that must be created by an individual developers credentials before automation can be run:
|
22
21
|
|
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
|
+
|
25
|
+
### Initial <%= use_gitlab_backend? ? "CI/CD pipeline" : "project" %> setup
|
24
26
|
|
25
27
|
These steps only need to be run once per project.
|
26
28
|
|
27
|
-
1. `cd bootstrap`<% if
|
28
|
-
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 %>
|
29
33
|
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/
|
33
|
-
1. Copy the cf_user and cf_password credentials from
|
34
|
-
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
|
35
40
|
|
36
41
|
### To make changes to the bootstrap module
|
37
42
|
|
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
|
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 %>*
|
39
44
|
|
40
45
|
1. Make your changes
|
41
|
-
1. Run `./apply.sh` and verify the plan before entering `yes
|
42
|
-
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 %>
|
43
48
|
|
44
|
-
|
49
|
+
<% if use_local_backend? %>
|
50
|
+
## Deploy the App
|
51
|
+
<% else %>
|
52
|
+
## Set up a sandbox environment or review app<% unless use_gitlab_backend? %>
|
45
53
|
|
46
54
|
### Pre-requisites:
|
47
55
|
|
48
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.
|
49
|
-
<% 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 %>
|
50
58
|
|
51
59
|
### Steps:
|
52
|
-
|
60
|
+
<% if use_gitlab_backend? %>
|
61
|
+
1. Run `./bootstrap/setup_shadowenv.sh`<% end %>
|
53
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
|
54
|
-
1. Add a `cf_user = "your.email@
|
63
|
+
1. Add a `cf_user = "your.email@gsa.gov"` line to the `sandbox-<NAME>.tfvars` file<% end %>
|
55
64
|
|
56
65
|
1. Run terraform plan with:
|
57
66
|
```bash
|
@@ -70,17 +79,19 @@ These steps only need to be run once per project.
|
|
70
79
|
|
71
80
|
## Structure
|
72
81
|
|
73
|
-
|
82
|
+
```<% unless use_local_backend? %>
|
74
83
|
|- bootstrap/
|
75
84
|
| |- main.tf
|
76
85
|
| |- apply.sh
|
86
|
+
| |- users.auto.tfvars<% if use_gitlab_backend? %>
|
87
|
+
| |- setup_shadowenv.sh
|
88
|
+
| |- bot_secrets.tftpl<% else %>
|
77
89
|
| |- imports.tf (automatically generated)
|
78
|
-
| |- users.auto.tfvars
|
79
90
|
| |- terraform.tfstate(.backup) (automatically generated)
|
80
91
|
| |- templates/
|
81
92
|
| |- backend_config.tftpl
|
82
93
|
| |- bot_secrets.tftpl
|
83
|
-
| |- imports.tf.tftpl
|
94
|
+
| |- imports.tf.tftpl<% end %><% end %>
|
84
95
|
|- dist/
|
85
96
|
| |- src.zip (automatically generated)
|
86
97
|
|- README.md
|
@@ -100,8 +111,9 @@ In the root module:
|
|
100
111
|
- `providers.tf` lists the required providers and shell backend config
|
101
112
|
- `variables.tf` lists the variables that will be needed
|
102
113
|
|
103
|
-
In the bootstrap module:
|
114
|
+
<% unless use_local_backend? %>In the bootstrap module:
|
104
115
|
- `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
|
106
|
-
- `
|
107
|
-
- `
|
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 %>
|
@@ -1,7 +1,7 @@
|
|
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
6
|
<% if terraform_manage_spaces? %>
|
7
7
|
module "app_space" {
|
@@ -9,7 +9,7 @@ module "app_space" {
|
|
9
9
|
|
10
10
|
cf_org_name = local.cf_org_name
|
11
11
|
cf_space_name = var.cf_space_name
|
12
|
-
allow_ssh = var.
|
12
|
+
allow_ssh = var.allow_ssh
|
13
13
|
deployers = local.space_deployers
|
14
14
|
developers = var.space_developers
|
15
15
|
auditors = var.space_auditors
|
@@ -3,16 +3,10 @@ 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
|
|
10
|
-
|
11
|
-
encrypt = true
|
12
|
-
use_lockfile = true
|
13
|
-
use_fips_endpoint = true
|
14
|
-
region = "us-gov-west-1"
|
15
|
-
}
|
16
|
-
}
|
10
|
+
<%= backend_block %>}
|
17
11
|
|
18
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,23 +84,34 @@ 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"
|
89
|
+
if [[ -f .terraform/terraform.tfstate ]]; then
|
90
|
+
backend_state_address=$(cat .terraform/terraform.tfstate | jq -r ".backend.config.address")
|
91
|
+
if [[ "$backend_state_address" = "$tf_state_address" ]]; then
|
92
|
+
tfm_needs_init=false
|
93
|
+
fi
|
94
|
+
fi<% elsif use_s3_backend? %>
|
74
95
|
if [[ -f .terraform/terraform.tfstate ]]; then
|
75
|
-
backend_state_env
|
96
|
+
backend_state_env=$(cat .terraform/terraform.tfstate | jq -r ".backend.config.key" | cut -d '.' -f3)
|
76
97
|
if [[ "$backend_state_env" = "$env" ]]; then
|
77
98
|
tfm_needs_init=false
|
78
99
|
fi
|
79
|
-
|
100
|
+
else
|
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 %>
|
80
107
|
|
81
|
-
if [[ $tfm_needs_init = true ]]; then
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
terraform init -backend-config=secrets.backend.tfvars -backend-config="key=terraform.tfstate.$env" -reconfigure
|
89
|
-
rm secrets.backend.tfvars
|
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 %>
|
90
115
|
fi
|
91
116
|
|
92
117
|
echo "=============================================================================================================="
|
@@ -1,9 +1,9 @@
|
|
1
|
-
|
1
|
+
<% if terraform_manage_spaces? %># Deploy user settings
|
2
2
|
variable "cf_user" {
|
3
3
|
type = string
|
4
4
|
description = "The user email or service account running the terraform"
|
5
5
|
}
|
6
|
-
|
6
|
+
<% end %>
|
7
7
|
# app_space settings
|
8
8
|
variable "cf_space_name" {
|
9
9
|
type = string
|
@@ -23,12 +23,12 @@ variable "space_auditors" {
|
|
23
23
|
type = set(string)
|
24
24
|
default = []
|
25
25
|
description = "A list of users to be granted SpaceAuditor on cf_space_name"
|
26
|
-
}
|
27
|
-
variable "
|
26
|
+
}<% end %>
|
27
|
+
variable "allow_ssh" {
|
28
28
|
type = bool
|
29
29
|
default = false
|
30
|
-
description = "Whether to allow ssh to
|
31
|
-
}
|
30
|
+
description = "Whether to allow ssh to the space and/or app"
|
31
|
+
}
|
32
32
|
|
33
33
|
# supporting services settings
|
34
34
|
variable "rds_plan_name" {
|
@@ -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,17 +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
40
|
remove_file "terraform/production.tfvars"
|
27
41
|
end
|
28
42
|
end
|
29
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
|
+
|
30
58
|
def ignore_files
|
31
59
|
unless skip_git?
|
32
60
|
append_to_file ".gitignore", <<~EOM
|
@@ -86,6 +114,51 @@ module RailsTemplate18f
|
|
86
114
|
done
|
87
115
|
EOM
|
88
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
|
89
162
|
end
|
90
163
|
end
|
91
164
|
end
|
data/template.rb
CHANGED
@@ -102,6 +102,10 @@ cloud_gov_production_space = default_prod_space if cloud_gov_production_space.bl
|
|
102
102
|
@gitlab_ci = yes?("Create GitLab CI config? (y/n)")
|
103
103
|
@github_actions = yes?("Create GitHub Actions? (y/n)")
|
104
104
|
@circleci_pipeline = yes?("Create CircleCI config? (y/n)")
|
105
|
+
local_terraform_backend = false
|
106
|
+
unless [@gitlab_ci, @github_actions, @circleci_pipeline].any?
|
107
|
+
local_terraform_backend = yes?("Use a local file to store terraform state? This is only appropriate for short-lived proofs of concept but will make it easier to deploy for a single dev. (y/n)")
|
108
|
+
end
|
105
109
|
newrelic = yes?("Create FEDRAMP New Relic config files? (y/n)")
|
106
110
|
dap = yes?("If this will be a public site, should we include Digital Analytics Program code? (y/n)")
|
107
111
|
supported_languages = []
|
@@ -128,22 +132,27 @@ register_announcement("Documentation", <<~EOM)
|
|
128
132
|
EOM
|
129
133
|
|
130
134
|
# do early so later generators register files in the correct location
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
135
|
+
run_oscal_generator = ->(register_announcement = false) {
|
136
|
+
if compliance_trestle
|
137
|
+
after_bundle do
|
138
|
+
generator_arguments = []
|
139
|
+
generator_arguments << "--oscal_repo=#{compliance_trestle_repo}" if compliance_trestle_submodule
|
140
|
+
generator_arguments << "--ci=github" if @github_actions
|
141
|
+
generator_arguments << "--ci=gitlab" if @gitlab_ci
|
142
|
+
generator_arguments << "--ci=circleci" if @circleci_pipeline
|
143
|
+
generate "rails_template18f:oscal", *generator_arguments
|
144
|
+
end
|
145
|
+
if register_announcement
|
146
|
+
register_announcement("OSCAL Documentation", <<~EOM)
|
147
|
+
OSCAL files have been generated with some default implementation statements in `doc/compliance/oscal`
|
142
148
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
end
|
149
|
+
All generated statements must be reviewed for accuracy with your system's implementation before being
|
150
|
+
submitted for authorization.
|
151
|
+
EOM
|
152
|
+
end
|
153
|
+
end
|
154
|
+
}
|
155
|
+
run_oscal_generator.call(true)
|
147
156
|
|
148
157
|
# ensure dependencies are installed
|
149
158
|
copy_file "Brewfile"
|
@@ -401,6 +410,11 @@ after_bundle do
|
|
401
410
|
"--cg-staging=#{cloud_gov_staging_space}",
|
402
411
|
"--cg-prod=#{cloud_gov_production_space}"
|
403
412
|
]
|
413
|
+
if @gitlab_ci
|
414
|
+
generator_arguments << "--backend=gitlab"
|
415
|
+
elsif local_terraform_backend
|
416
|
+
generator_arguments << "--backend=local"
|
417
|
+
end
|
404
418
|
generate "rails_template18f:terraform", *generator_arguments
|
405
419
|
end
|
406
420
|
if cloud_gov_org_tktk?
|
@@ -467,6 +481,9 @@ if @gitlab_ci
|
|
467
481
|
EOM
|
468
482
|
end
|
469
483
|
|
484
|
+
# rerun so we can update the correct CI systems
|
485
|
+
run_oscal_generator.call
|
486
|
+
|
470
487
|
if auditree
|
471
488
|
after_bundle do
|
472
489
|
generate "rails_template18f:auditree", "--evidence_locker=#{auditree_evidence_repo}"
|