rails_template_18f 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/Gemfile.lock +85 -70
  4. data/lib/generators/rails_template18f/active_storage/active_storage_generator.rb +4 -3
  5. data/lib/generators/rails_template18f/auditree/auditree_generator.rb +36 -6
  6. data/lib/generators/rails_template18f/auditree/templates/gitlab/auditree.yml.tt +48 -0
  7. data/lib/generators/rails_template18f/circleci/templates/circleci/config.yml.tt +6 -2
  8. data/lib/generators/rails_template18f/cloud_gov_config/cloud_gov_config_generator.rb +0 -8
  9. data/lib/generators/rails_template18f/cloud_gov_config/templates/app/models/cloud_gov_config.rb +6 -15
  10. data/lib/generators/rails_template18f/cloud_gov_config/templates/spec/models/cloud_gov_config_spec.rb +13 -19
  11. data/lib/generators/rails_template18f/github_actions/github_actions_generator.rb +0 -4
  12. data/lib/generators/rails_template18f/github_actions/templates/github/dependabot.yml.tt +16 -0
  13. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-production.yml +4 -1
  14. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml +4 -1
  15. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-production.yml +4 -1
  16. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-staging.yml +4 -1
  17. data/lib/generators/rails_template18f/gitlab_ci/gitlab_ci_generator.rb +9 -18
  18. data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/{node.yml.tt → node.yml} +1 -1
  19. data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/rails.yml +11 -18
  20. data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab-ci.yml.tt +80 -152
  21. data/lib/generators/rails_template18f/oscal/oscal_generator.rb +15 -1
  22. data/lib/generators/rails_template18f/oscal/templates/bin/trestle.tt +10 -1
  23. data/lib/generators/rails_template18f/oscal/templates/gitlab/trestle.yml.tt +29 -0
  24. data/lib/generators/rails_template18f/public_egress/public_egress_generator.rb +2 -2
  25. data/lib/generators/rails_template18f/sidekiq/templates/config/initializers/redis.rb +1 -1
  26. data/lib/generators/rails_template18f/terraform/templates/gitlab_bootstrap/apply.sh +25 -0
  27. data/lib/generators/rails_template18f/terraform/templates/gitlab_bootstrap/main.tf.tt +114 -0
  28. data/lib/generators/rails_template18f/terraform/templates/gitlab_bootstrap/setup_shadowenv.sh +61 -0
  29. data/lib/generators/rails_template18f/terraform/templates/s3_bootstrap/common/templates/backend_config.tftpl +6 -0
  30. data/lib/generators/rails_template18f/terraform/templates/s3_bootstrap/common/users.auto.tfvars +5 -0
  31. data/lib/generators/rails_template18f/terraform/templates/{full_bootstrap → s3_bootstrap/full}/main.tf.tt +7 -27
  32. data/lib/generators/rails_template18f/terraform/templates/{sandbox_bootstrap → s3_bootstrap/sandbox}/main.tf.tt +6 -19
  33. data/lib/generators/rails_template18f/terraform/templates/terraform/.shadowenv.d/.gitignore +3 -0
  34. data/lib/generators/rails_template18f/terraform/templates/terraform/README.md.tt +41 -29
  35. data/lib/generators/rails_template18f/terraform/templates/terraform/app.tf.tt +7 -6
  36. data/lib/generators/rails_template18f/terraform/templates/terraform/main.tf.tt +16 -14
  37. data/lib/generators/rails_template18f/terraform/templates/terraform/{production.tfvars.tt → production.env.tfvars.tt} +0 -1
  38. data/lib/generators/rails_template18f/terraform/templates/terraform/providers.tf.tt +6 -8
  39. data/lib/generators/rails_template18f/terraform/templates/terraform/staging.env.tfvars.tt +7 -0
  40. data/lib/generators/rails_template18f/terraform/templates/terraform/terraform.sh.tt +52 -18
  41. data/lib/generators/rails_template18f/terraform/templates/terraform/variables.tf.tt +15 -11
  42. data/lib/generators/rails_template18f/terraform/terraform_generator.rb +80 -6
  43. data/lib/rails_template18f/generators/cloud_gov_parsing.rb +2 -2
  44. data/lib/rails_template18f/version.rb +1 -1
  45. data/template.rb +33 -16
  46. data/templates/README.md.tt +1 -1
  47. metadata +23 -17
  48. data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/terraform.yml +0 -28
  49. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/templates/backend_config.tftpl +0 -8
  50. data/lib/generators/rails_template18f/terraform/templates/terraform/staging.tfvars.tt +0 -8
  51. /data/lib/generators/rails_template18f/{github_actions → oscal}/templates/github/workflows/assemble-ssp.yml.tt +0 -0
  52. /data/lib/generators/rails_template18f/{github_actions → oscal}/templates/github/workflows/validate-ssp.yml +0 -0
  53. /data/lib/generators/rails_template18f/terraform/templates/{terraform/bootstrap → gitlab_bootstrap}/users.auto.tfvars +0 -0
  54. /data/lib/generators/rails_template18f/terraform/templates/{terraform/bootstrap → s3_bootstrap/common}/apply.sh +0 -0
  55. /data/lib/generators/rails_template18f/terraform/templates/{terraform/bootstrap → s3_bootstrap/common}/templates/bot_secrets.tftpl +0 -0
  56. /data/lib/generators/rails_template18f/terraform/templates/{full_bootstrap → s3_bootstrap/full}/imports.tf.tftpl +0 -0
  57. /data/lib/generators/rails_template18f/terraform/templates/{sandbox_bootstrap → s3_bootstrap/sandbox}/imports.tf.tftpl +0 -0
@@ -49,7 +49,7 @@ module RailsTemplate18f
49
49
  def update_boundary_diagram
50
50
  boundary_filename = "doc/compliance/apps/application.boundary.md"
51
51
  insert_into_file boundary_filename, <<EOB, after: "Boundary(cicd, \"CI/CD Pipeline\") {\n"
52
- System_Ext(gitlabci, "GitLab w/ DevTools Runner", "GSA-controlled code repository and Continuous Integration Service")
52
+ System_Ext(gitlabci, "Cloud.gov Workshop", "GSA-run code repository and Continuous Integration Service")
53
53
  EOB
54
54
  insert_into_file boundary_filename, <<~EOB, before: "@enduml"
55
55
  Rel(developer, gitlabci, "Publish code", "git ssh (22)")
@@ -76,10 +76,9 @@ EOB
76
76
 
77
77
  | Secret Name | Description |
78
78
  | ----------- | ----------- |
79
- | `CF_USERNAME` | cloud.gov SpaceDeployer username |
80
- | `CF_PASSWORD` | cloud.gov SpaceDeployer password |
79
+ | `CF_USER` | cloud.gov OrgManager username |
80
+ | `CF_PASSWORD` | cloud.gov OrgManager password |
81
81
  | `RAILS_MASTER_KEY` | `config/master.key` |
82
- #{terraform_secret_values}
83
82
  EOM
84
83
  end
85
84
 
@@ -87,16 +86,15 @@ EOB
87
86
  if terraform_manage_spaces?
88
87
  <<~EOM
89
88
 
90
- Deploys to production happen via terraform on every push to the `production` branch in GitLab.
89
+ Deploys to production happen via terraform on every tag that is added to the `main` branch.
91
90
 
92
- The following secrets must be set within the masked and hidden [CI/CD variables](https://docs.gitlab.com/ci/variables/)
91
+ The following secrets must be set within the masked and hidden [CI/CD variables](https://docs.gitlab.com/ci/variables/) and assigned to the `production` environment.
93
92
 
94
93
  | Secret Name | Description |
95
94
  | ----------- | ----------- |
96
- | `CF_USERNAME` | cloud.gov SpaceDeployer username |
97
- | `CF_PASSWORD` | cloud.gov SpaceDeployer password |
98
- | `PRODUCTION_RAILS_MASTER_KEY` | `config/credentials/production.key`. Should be marked as `Protected`. |
99
- #{terraform_secret_values}
95
+ | `CF_USER` | cloud.gov OrgManager username |
96
+ | `CF_PASSWORD` | cloud.gov OrgManager password |
97
+ | `RAILS_MASTER_KEY` | `config/credentials/production.key`. Should be marked as `Protected`. |
100
98
  EOM
101
99
  else
102
100
  "Production deploys are not supported in the sandbox organization."
@@ -107,20 +105,13 @@ EOB
107
105
  <<~EOM
108
106
 
109
107
  1. Store variables that must be secret using masked and hidden [CI/CD variables](https://docs.gitlab.com/ci/variables/) in GitLab
110
- 1. Add the appropriate `-var` arguments to the `terraform:plan:<env>` and `terraform:apply:<env>` jobs like the existing `-var rails_master_key=`
108
+ 1. Add the appropriate `TF_VAR_` prefixed variables for the `terraform:plan:<env>` and `terraform:apply:<env>` jobs like the existing `TF_VAR_rails_master_key`
111
109
  EOM
112
110
  end
113
111
  end
114
112
 
115
113
  private
116
114
 
117
- def terraform_secret_values
118
- <<~EOM
119
- | `TERRAFORM_PUBLIC_BACKEND_CONFIG` | File-type variable containing all entries from secrets.backend.tfvars _except_ `secret_key`. Marked as `Visible` |
120
- | `TERRAFORM_SECRET_BACKEND_CONFIG` | File-type variable containing the `secret_key` line from secrets.backend.tfvars. Masked and hidden. |
121
- EOM
122
- end
123
-
124
115
  def postgres_version
125
116
  options[:postgres_version]
126
117
  end
@@ -1,5 +1,5 @@
1
1
  .setup-node:
2
- - curl -fsSL https://deb.nodesource.com/setup_<%= node_major %>.x -o nodesource_setup.sh
2
+ - curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR_VERSION}.x" -o nodesource_setup.sh
3
3
  - bash nodesource_setup.sh
4
4
  - apt-get install -y nodejs
5
5
  - npm install --global yarn
@@ -2,6 +2,13 @@ include:
2
2
  - local: ".gitlab/ruby.yml"
3
3
  - local: ".gitlab/node.yml"
4
4
 
5
+ .base:
6
+ image: "ruby:${RUBY_VERSION}"
7
+ before_script:
8
+ - !reference [.setup-ruby]
9
+ cache:
10
+ - !reference [.cache-dependencies, cache]
11
+
5
12
  # Cache Helpers
6
13
  .cache-dependencies:
7
14
  variables:
@@ -15,27 +22,28 @@ include:
15
22
  paths:
16
23
  - vendor/ruby
17
24
  - node_modules/
18
- policy: pull
19
25
 
20
26
  # Language Helpers
21
27
  .setup-languages:
28
+ extends: .base
22
29
  before_script:
23
30
  - !reference [.setup-ruby]
24
31
  - !reference [.setup-node]
25
32
 
26
33
  # Project Helpers
27
34
  .setup-project:
35
+ extends: .base
28
36
  services:
29
37
  - name: "postgres:${POSTGRES_VERSION}"
30
38
  alias: pg
39
+ variables:
40
+ DATABASE_URL: "postgres://postgres:${POSTGRES_PASSWORD}@${WSR_SERVICE_HOST_pg}:5432/${POSTGRES_DB}"
31
41
  before_script:
32
42
  - !reference [.setup-ruby]
33
- - export DATABASE_URL="postgres://postgres:${POSTGRES_PASSWORD}@${CI_SERVICE_pg}:5432/${POSTGRES_DB}"
34
43
  - bin/rails db:prepare
35
44
 
36
45
  .run-server:
37
46
  extends: .setup-project
38
- dependencies: []
39
47
  variables:
40
48
  RAILS_ENV: ci
41
49
  SECRET_KEY_BASE_DUMMY: 1
@@ -46,21 +54,6 @@ include:
46
54
  - PORT=3000 bin/rails server > /dev/null 2>&1 &
47
55
  - sleep 5
48
56
 
49
- .owasp:setup:
50
- stage: test
51
- extends: .run-server
52
- image: "rcahearngsa/owasp-ruby:${RUBY_VERSION}"
53
- variables:
54
- WORKER_MEMORY: 3G
55
- WORKER_DISK: 6G
56
- before_script:
57
- - !reference [.run-server, before_script]
58
- - ln -s $PWD /zap/wrk
59
- artifacts:
60
- expose_as: "OWASP Report"
61
- paths:
62
- - zap_report.html
63
-
64
57
  .assets:builder:
65
58
  stage: deploy
66
59
  extends: .setup-languages
@@ -1,41 +1,94 @@
1
1
  # Note that environment variables can be set in several places
2
2
  # See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
3
+ spec:
4
+ inputs:
5
+ enable-staging-deploy:
6
+ type: boolean
7
+ default: true
8
+ description: "Set to false for scheduled pipelines"
9
+ disable-tflint:
10
+ type: boolean
11
+ default: false
12
+ description: "Set to true for scheduled pipelines"
13
+ enable-tf-fmt:
14
+ type: boolean
15
+ default: true
16
+ description: "Set to false for scheduled pipelines"
17
+ ---
3
18
 
4
19
  workflow:
5
20
  rules:
6
21
  - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
22
+ - if: $CI_PIPELINE_SOURCE == 'web'
7
23
  - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
8
- - if: $CI_COMMIT_BRANCH == "production"
24
+ - if: $CI_COMMIT_TAG =~ /^v?\d+\.\d+\.\d+$/
9
25
 
10
26
  stages:
11
27
  - build
12
28
  - test
13
- - deploy
29
+ - publish
30
+ - infra
31
+ - dast
32
+ - infra-prod
14
33
 
15
34
  variables:
16
35
  POSTGRES_DB: <%= app_name %>_test
17
36
  POSTGRES_PASSWORD: not-actually-secret
18
37
  POSTGRES_VERSION: <%= postgres_version %>
19
38
  RUBY_VERSION: <%= RUBY_VERSION %>
39
+ NODE_MAJOR_VERSION: <%= node_major %>
40
+ CF_API_URL: https://api.fr.cloud.gov
41
+ TF_VAR_cf_user: $CF_USER
42
+ TF_VAR_rails_master_key: $RAILS_MASTER_KEY
20
43
 
21
44
  include:
22
45
  - local: ".gitlab/ruby.yml"
23
46
  - local: ".gitlab/node.yml"
24
47
  - local: ".gitlab/rails.yml"
25
- - local: ".gitlab/terraform.yml"
48
+ - template: Jobs/SAST.gitlab-ci.yml
49
+ - template: Jobs/SAST-IaC.gitlab-ci.yml
50
+ - template: Security/DAST.gitlab-ci.yml
51
+ - template: Jobs/Dependency-Scanning.latest.gitlab-ci.yml
52
+ - template: Jobs/Secret-Detection.gitlab-ci.yml
53
+ - component: $CI_SERVER_FQDN/components/terraform/gitlab-ci-terraform@8
54
+ inputs:
55
+ project-dir: terraform
56
+ fmt-enabled: $[[ inputs.enable-tf-fmt ]]
57
+ tflint-disabled: $[[ inputs.disable-tflint ]]
58
+ validate-enabled: true
59
+ review-enabled: true
60
+ review-autostop-duration: "1 week"
61
+ staging-enabled: $[[ inputs.enable-staging-deploy ]]
62
+ prod-enabled: false # Switch to true when your project is ready for prod deploys
63
+ prod-plan-enabled: true
64
+
65
+ check-tag-on-main:
66
+ stage: .pre
67
+ variables:
68
+ GIT_STRATEGY: clone
69
+ GIT_DEPTH: 0
70
+ script:
71
+ - git branch -r --contains "$CI_COMMIT_TAG" | grep "^\s*origin/${CI_DEFAULT_BRANCH}\$"
72
+ rules:
73
+ - if: $CI_COMMIT_TAG
26
74
 
27
- default:
28
- image: "ruby:${RUBY_VERSION}"
29
- before_script:
30
- - !reference [.setup-ruby]
31
- cache:
32
- - !reference [.cache-dependencies, cache]
75
+ tf-review:
76
+ environment:
77
+ url: "https://<%= app_name.tr("_", "-") %>-${CI_ENVIRONMENT_SLUG}.app.cloud.gov"
78
+ on_stop: tf-destroy-review
79
+
80
+ tf-staging:
81
+ environment:
82
+ url: "https://<%= app_name.tr("_", "-") %>-${CI_ENVIRONMENT_SLUG}.app.cloud.gov"
83
+ on_stop: tf-destroy-staging
84
+
85
+ tf-production:
86
+ environment:
87
+ url: "https://<%= app_name.tr("_", "-") %>-${CI_ENVIRONMENT_SLUG}.app.cloud.gov"
33
88
 
34
89
  build-project:
35
90
  stage: build
36
91
  extends: [.cache-dependencies, .setup-languages]
37
- cache:
38
- policy: pull-push
39
92
  script:
40
93
  - !reference [.bundle-install]
41
94
  - !reference [.yarn-install]
@@ -48,31 +101,9 @@ build-project:
48
101
  rules:
49
102
  - if: $CI_PIPELINE_SOURCE != "schedule"
50
103
 
51
- brakeman-scan:
52
- stage: test
53
- script:
54
- - bin/brakeman --no-pager --ensure-ignore-notes -f sarif -o output.sarif.json
55
- artifacts:
56
- when: always
57
- expose_as: "Brakeman results"
58
- paths:
59
- - output.sarif.json
60
-
61
- dependency_scanning:
62
- stage: test
63
- extends: .setup-languages
64
- script:
65
- - bin/rake bundler:audit
66
- - bin/rake yarn:audit
67
- - gem install cyclonedx-ruby
68
- - cyclonedx-ruby -p . -o ruby_bom.xml
69
- artifacts:
70
- expose_as: "Ruby SBOM"
71
- paths:
72
- - ruby_bom.xml
73
-
74
104
  rspec:
75
105
  stage: test
106
+ needs: ["build-project"]
76
107
  extends: .setup-project
77
108
  script:
78
109
  - bundle exec rspec
@@ -81,6 +112,7 @@ rspec:
81
112
 
82
113
  pa11y_scan:
83
114
  stage: test
115
+ needs: ["build-project"]
84
116
  extends: .run-server
85
117
  script:
86
118
  - !reference [.install-puppet-deps]
@@ -88,125 +120,21 @@ pa11y_scan:
88
120
  rules:
89
121
  - if: $CI_PIPELINE_SOURCE != "schedule"
90
122
 
91
- owasp_scan:
92
- extends: .owasp:setup
93
- script:
94
- - /zap/zap-baseline.py -t http://localhost:3000 -c zap.conf -I -r zap_report.html
95
- rules:
96
- - if: $CI_PIPELINE_SOURCE != "schedule"
97
-
98
- owasp_daily_scan:
99
- extends: .owasp:setup
100
- script:
101
- - /zap/zap-full-scan.py -t http://localhost:3000 -c zap.conf -I -r zap_report.html
102
- rules:
103
- - if: $CI_PIPELINE_SOURCE == "schedule"
104
-
105
- terraform:fmt:
106
- stage: test
107
- extends: .terraform:setup
108
- script:
109
- - terraform fmt -check -recursive .
110
-
111
- terraform:validate:
112
- stage: test
113
- extends: .terraform:setup
114
- script:
115
- - terraform validate
116
-
117
- terraform:assets:staging:
118
- extends: .assets:builder
119
- cache:
120
- - !reference [.cache-dependencies, cache]
121
- - key: staging-assets
122
- unprotect: true
123
- paths:
124
- - public/assets
125
- - app/assets/builds
126
- policy: $CACHE_POLICY
127
- variables:
128
- RAILS_ENV: staging
129
- rules:
130
- - if: $CI_PIPELINE_SOURCE == "schedule"
131
- when: never
132
- - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
133
- variables:
134
- CACHE_POLICY: pull-push
135
- - variables:
136
- CACHE_POLICY: pull
137
- <% if terraform_manage_spaces? %>
138
- terraform:assets:production:
139
- extends: .assets:builder
140
- cache:
141
- - !reference [.cache-dependencies, cache]
142
- - key: production-assets
143
- paths:
144
- - public/assets
145
- - app/assets/builds
146
- policy: $CACHE_POLICY
123
+ dast:
124
+ environment:
125
+ name: $DAST_ENVIRONMENT_NAME
126
+ action: access
147
127
  variables:
148
- RAILS_ENV: production
149
- rules:
150
- - if: $CI_COMMIT_BRANCH == "production"
151
- variables:
152
- CACHE_POLICY: pull-push
153
- - if: $CI_PIPELINE_SOURCE != "schedule"
154
- variables:
155
- CACHE_POLICY: pull
156
- <% end %>
157
- terraform:plan:staging:
158
- extends:
159
- - .terraform:setup
160
- - .terraform:variables:staging
161
- needs: ["terraform:assets:staging"]
128
+ DAST_TARGET_URL: "https://<%= app_name.tr("_", "-") %>-${CI_ENVIRONMENT_SLUG}.app.cloud.gov"
129
+ DAST_IMAGE_SUFFIX: "-fips"
130
+ tags:
131
+ - unsafe_egress
162
132
  script:
163
- - apk add zip
164
- - terraform plan -out=staging_plan.out -var-file=staging.tfvars -var rails_master_key=$RAILS_MASTER_KEY -var cf_user=$CF_USERNAME
165
- artifacts:
166
- paths:
167
- - terraform/staging_plan.out
168
- - terraform/dist
169
-
170
- terraform:apply:staging:
171
- extends:
172
- - .terraform:setup
173
- - .terraform:variables:staging
174
- needs:
175
- - terraform:plan:staging
176
- - terraform:assets:staging
177
- script:
178
- - apk add zip
179
- - terraform apply -var-file=staging.tfvars -var rails_master_key=$RAILS_MASTER_KEY -var cf_user=$CF_USERNAME staging_plan.out
133
+ - /browserker/entrypoint.sh /analyze
180
134
  rules:
181
- - if: $CI_PIPELINE_SOURCE == "schedule"
182
- when: never
135
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
136
+ variables:
137
+ DAST_ENVIRONMENT_NAME: "review/$CI_COMMIT_REF_NAME"
183
138
  - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
184
- <% if terraform_manage_spaces? %>
185
- terraform:plan:production:
186
- extends:
187
- - .terraform:setup
188
- - .terraform:variables:production
189
- needs: ["terraform:assets:production"]
190
- script:
191
- - apk add zip
192
- - terraform plan -out=production_plan.out -var-file=production.tfvars -var rails_master_key=$PRODUCTION_RAILS_MASTER_KEY -var cf_user=$CF_USERNAME
193
- artifacts:
194
- paths:
195
- - terraform/production_plan.out
196
- - terraform/dist
197
-
198
- terraform:apply:production:
199
- extends:
200
- - .terraform:setup
201
- - .terraform:variables:production
202
- needs:
203
- - terraform:plan:production
204
- - terraform:assets:production
205
- script:
206
- - apk add zip
207
- - terraform apply -var-file=production.tfvars -var rails_master_key=$PRODUCTION_RAILS_MASTER_KEY -var cf_user=$CF_USERNAME production_plan.out
208
- rules:
209
- - if: $CI_PIPELINE_SOURCE == "schedule"
210
- when: never
211
- - if: $CI_COMMIT_BRANCH == "production"
212
- when: manual<% end %>
139
+ variables:
140
+ DAST_ENVIRONMENT_NAME: "staging"
@@ -49,6 +49,16 @@ module RailsTemplate18f
49
49
  end
50
50
  end
51
51
 
52
+ def copy_gitlab_ci
53
+ if use_gitlab_ci?
54
+ directory "gitlab", ".gitlab"
55
+ if file_exists? ".gitlab-ci.yml"
56
+ insert_into_file ".gitlab-ci.yml", " - local: \".gitlab/trestle.yml\"\n", after: /^include:\n/
57
+ insert_into_file ".gitlab-ci.yml", " TRESTLE_VERSION: #{docker_trestle_tag}\n", after: /^variables:\n/
58
+ end
59
+ end
60
+ end
61
+
52
62
  def update_readme
53
63
  if file_content("README.md").match?("## Documentation")
54
64
  insert_into_file "README.md", readme_contents, after: "## Documentation\n"
@@ -85,13 +95,17 @@ module RailsTemplate18f
85
95
  end
86
96
 
87
97
  def docker_trestle_tag
88
- options[:tag].present? ? options[:tag] : "20240912"
98
+ options[:tag].present? ? options[:tag] : "20250603"
89
99
  end
90
100
 
91
101
  def use_github_actions?
92
102
  options[:ci] == "github" || file_exists?(".github/workflows")
93
103
  end
94
104
 
105
+ def use_gitlab_ci?
106
+ options[:ci] == "gitlab" || file_exists?(".gitlab-ci.yml")
107
+ end
108
+
95
109
  def readme_contents
96
110
  content = <<~README
97
111
 
@@ -2,8 +2,17 @@
2
2
 
3
3
  trestle_tag="<%= docker_trestle_tag %>"
4
4
 
5
+ if [ "$1" = "-h" ]; then
6
+ echo """
7
+ Usage: $0 [-h] [CMD [CMD ARGS]]
8
+
9
+ CMD defaults to 'bash'
10
+ """
11
+ exit 0
12
+ fi
13
+
5
14
  command="bash"
6
- if [ "$1" != "" ]; then
15
+ if [ -n "$1" ]; then
7
16
  command=$1
8
17
  shift 1
9
18
  fi
@@ -0,0 +1,29 @@
1
+ .trestle:setup:
2
+ inherit:
3
+ default: false
4
+ image: "ghcr.io/gsa-tts/trestle:${TRESTLE_VERSION}"
5
+ before_script:
6
+ - cd doc/compliance/oscal
7
+ - export PATH="/app/bin:$PATH"
8
+
9
+ validate_ssp:
10
+ extends: .trestle:setup
11
+ stage: test
12
+ script:
13
+ - validate-ssp-json
14
+ rules:
15
+ - if: $CI_PIPELINE_SOURCE != "schedule"
16
+
17
+ assemble_ssp:
18
+ extends: .trestle:setup
19
+ stage: deploy
20
+ script:
21
+ - trestle assemble -n <%= app_name %> system-security-plan
22
+ - render-ssp
23
+ artifacts:
24
+ expose_as: "<%= app_name %> SSPP"
25
+ paths:
26
+ - doc/compliance/oscal/dist/system-security-plans/<%= app_name %>.json
27
+ - doc/compliance/oscal/ssp-render/<%= app_name %>_ssp.md
28
+ rules:
29
+ - if: $CI_PIPELINE_SOURCE != "schedule"
@@ -88,7 +88,7 @@ EOB
88
88
  ### Public Egress Proxy
89
89
 
90
90
  Traffic to be delivered to the public internet must be proxied through the [cg-egress-proxy](https://github.com/GSA-TTS/cg-egress-proxy) app. Hostnames that the app should be able to
91
- reach should be added to the `egress_allowlist` terraform variable in `terraform/production.tfvars` and `terraform/staging.tfvars`
91
+ reach should be added to the `egress_allowlist` terraform variable in `terraform/production.env.tfvars` and `terraform/staging.env.tfvars`
92
92
 
93
93
  See the [ruby troubleshooting doc](https://github.com/GSA-TTS/cg-egress-proxy/blob/main/docs/ruby.md) first if you have any problems making outbound connections through the proxy.
94
94
 
@@ -103,7 +103,7 @@ EOB
103
103
 
104
104
  cf_org_name = local.cf_org_name
105
105
  cf_space_name = "${var.cf_space_name}-egress"
106
- allow_ssh = var.allow_space_ssh
106
+ allow_ssh = var.allow_ssh
107
107
  deployers = local.space_deployers
108
108
  developers = var.space_developers
109
109
  auditors = var.space_auditors
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Rails.application.config.to_prepare do
4
- redis_url = CloudGovConfig.dig "aws-elasticache-redis", "credentials", "uri"
4
+ redis_url = CloudGovConfig.new.dig "aws-elasticache-redis", "credentials", "uri"
5
5
  if redis_url.present?
6
6
  Sidekiq.configure_server do |config|
7
7
  config.redis = {url: redis_url, ssl: true}
@@ -0,0 +1,25 @@
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
+ if [ -z "$GITLAB_PROJECT_ID" ] || [ -z "$GITLAB_BASE_URL" ]; then
10
+ echo "GITLAB_PROJECT_ID or GITLAB_BASE_URL has not been set. Run ./setup_shadowenv.sh first"
11
+ exit 1
12
+ fi
13
+
14
+ set -e
15
+
16
+ # ensure we're logged in via cli
17
+ cf spaces &> /dev/null || cf login -a api.fr.cloud.gov --sso
18
+
19
+ tf_state_address="$GITLAB_BASE_URL/projects/$GITLAB_PROJECT_ID/terraform/state/bootstrap"
20
+ terraform init \
21
+ -backend-config="address=$tf_state_address" \
22
+ -backend-config="lock_address=$tf_state_address/lock" \
23
+ -backend-config="unlock_address=$tf_state_address/lock"
24
+
25
+ terraform apply -var project_id="$GITLAB_PROJECT_ID" "$@"
@@ -0,0 +1,114 @@
1
+ terraform {
2
+ required_version = "~> 1.10"
3
+ required_providers {
4
+ cloudfoundry = {
5
+ source = "cloudfoundry/cloudfoundry"
6
+ version = "~> 1.10"
7
+ }
8
+ gitlab = {
9
+ source = "gitlabhq/gitlab"
10
+ version = "~> 18.5"
11
+ }
12
+ }
13
+ backend "http" {
14
+ lock_method = "POST"
15
+ unlock_method = "DELETE"
16
+ retry_wait_min = 5
17
+ }
18
+ }
19
+ # empty config will let terraform borrow cf-cli's auth
20
+ provider "cloudfoundry" {}
21
+ provider "gitlab" {}
22
+
23
+ locals {
24
+ org_name = "<%= cloud_gov_organization %>"
25
+ space_name = "<%= terraform_manage_spaces? ? "#{ cloud_gov_production_space }-mgmt" : cloud_gov_staging_space %>"
26
+ }
27
+
28
+ data "cloudfoundry_org" "org" {
29
+ name = local.org_name
30
+ }
31
+
32
+ variable "project_id" {
33
+ type = number
34
+ description = "The GitLab project ID for this project"
35
+ }
36
+
37
+ <% if terraform_manage_spaces? %>
38
+ variable "terraform_users" {
39
+ type = set(string)
40
+ description = "The list of developer emails and service account usernames who should be able to update the service bot user"
41
+
42
+ validation {
43
+ condition = length(var.terraform_users) > 0
44
+ error_message = "terraform_users must include at least the current user calling apply.sh"
45
+ }
46
+ }
47
+
48
+ module "mgmt_space" {
49
+ source = "github.com/gsa-tts/terraform-cloudgov//cg_space?ref=v2.3.0"
50
+
51
+ cf_org_name = local.org_name
52
+ cf_space_name = local.space_name
53
+ developers = var.terraform_users
54
+ }
55
+ <% else %>
56
+ data "cloudfoundry_space" "space" {
57
+ name = local.space_name
58
+ org = data.cloudfoundry_org.org.id
59
+ }
60
+ <% end %>
61
+ data "cloudfoundry_service_plans" "cg_service_account" {
62
+ name = "<%= terraform_manage_spaces? ? "space-auditor" : "space-deployer" %>"
63
+ service_offering_name = "cloud-gov-service-account"
64
+ }
65
+ resource "cloudfoundry_service_instance" "runner_service_account" {
66
+ name = "<%= app_name %>-cicd-deployer"
67
+ type = "managed"
68
+ service_plan = data.cloudfoundry_service_plans.cg_service_account.service_plans[0].id<% if terraform_manage_spaces? %>
69
+ space = module.mgmt_space.space_id
70
+ depends_on = [module.mgmt_space]<% else %>
71
+ space = data.cloudfoundry_space.space.id<% end %>
72
+ }
73
+ resource "cloudfoundry_service_credential_binding" "runner_sa_key" {
74
+ name = "cicd-deployer-access-key"
75
+ service_instance = cloudfoundry_service_instance.runner_service_account.id
76
+ type = "key"
77
+ }
78
+ locals {
79
+ sa_bot_credentials = jsondecode(cloudfoundry_service_credential_binding.runner_sa_key.credential_binding).credentials
80
+ sa_cf_username = nonsensitive(local.sa_bot_credentials.username)
81
+ sa_cf_password = local.sa_bot_credentials.password
82
+ }<% if terraform_manage_spaces? %>
83
+ data "cloudfoundry_user" "sa_user" {
84
+ name = local.sa_cf_username
85
+ }
86
+ resource "cloudfoundry_org_role" "sa_org_manager" {
87
+ user = data.cloudfoundry_user.sa_user.users[0].id
88
+ type = "organization_manager"
89
+ org = data.cloudfoundry_org.org.id
90
+ }<% end %>
91
+
92
+ resource "gitlab_project_variable" "cf_user" {
93
+ project = var.project_id
94
+ key = "CF_USER"
95
+ value = local.sa_cf_username
96
+ protected = false
97
+ masked = false
98
+ hidden = false
99
+ raw = true
100
+ variable_type = "env_var"
101
+ description = "Set by terraform bootstrap module"
102
+ }
103
+
104
+ resource "gitlab_project_variable" "cf_password" {
105
+ project = var.project_id
106
+ key = "CF_PASSWORD"
107
+ value = local.sa_cf_password
108
+ protected = false
109
+ masked = true
110
+ hidden = true
111
+ raw = true
112
+ variable_type = "env_var"
113
+ description = "Set by terraform bootstrap module"
114
+ }