rails_template_18f 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/Gemfile.lock +29 -31
  4. data/lib/generators/rails_template18f/circleci/templates/circleci/config.yml.tt +5 -0
  5. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-production.yml.tt +8 -0
  6. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml.tt +8 -0
  7. data/lib/generators/rails_template18f/i18n_js/i18n_js_generator.rb +12 -20
  8. data/lib/generators/rails_template18f/i18n_js/templates/app/javascript/i18n.js +11 -0
  9. data/lib/generators/rails_template18f/i18n_js/templates/config/i18n-js.yml +4 -0
  10. data/lib/generators/rails_template18f/i18n_js/templates/config/initializers/i18n_js.rb +5 -0
  11. data/lib/generators/rails_template18f/i18n_js/templates/lib/tasks/i18n.rake +8 -7
  12. data/lib/generators/rails_template18f/public_egress/public_egress_generator.rb +136 -0
  13. data/lib/generators/rails_template18f/terraform/templates/terraform/README.md.tt +2 -2
  14. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/main.tf.tt +1 -1
  15. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/run.sh.tt +2 -1
  16. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/teardown_creds.sh.tt +1 -1
  17. data/lib/generators/rails_template18f/terraform/templates/terraform/production/main.tf.tt +25 -5
  18. data/lib/generators/rails_template18f/terraform/templates/terraform/staging/main.tf.tt +22 -4
  19. data/lib/rails_template18f/generators/base.rb +7 -0
  20. data/lib/rails_template18f/generators/cloud_gov_options.rb +7 -27
  21. data/lib/rails_template18f/generators/cloud_gov_parsing.rb +41 -0
  22. data/lib/rails_template18f/generators.rb +1 -0
  23. data/lib/rails_template18f/version.rb +1 -1
  24. data/templates/bin/ops/create_service_account.sh.tt +14 -2
  25. data/templates/bin/ops/destroy_service_account.sh.tt +0 -3
  26. data/templates/manifest.yml.tt +1 -1
  27. metadata +9 -4
  28. /data/lib/generators/rails_template18f/terraform/templates/terraform/production/{providers.tf.tt → providers.tf} +0 -0
  29. /data/lib/generators/rails_template18f/terraform/templates/terraform/staging/{providers.tf.tt → providers.tf} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 957ad56e218689b3d05f7c31ae6354a4e2c42877567ea87478845b30129cef43
4
- data.tar.gz: f5d6045a2632863b50209c557f7460f61f9bacb90a99883b6b090f6580c528d0
3
+ metadata.gz: 24d43ee8d10fdaa457658cfab2ce12e28e9d65364147ad46e96ef8d8d2f6f15c
4
+ data.tar.gz: 686546614e2d8205fce7ccd575842645effeb30add6d08fe3057b6623f1800f6
5
5
  SHA512:
6
- metadata.gz: ea0332afd7b819bcd2b03acca406467f9404de6f8e065e980bdabf81ef7083377f8dfc4d6754baaf1a4e6525eaa5190402f7a5307d35fb472960089a62ddba9e
7
- data.tar.gz: 5720c1340a3065354de210dd4deccb5577656876501514ac09faf91a133511e92796e0cb18aee299e8894b16394fbacde12419e6c97795a3be086242e9afa815
6
+ metadata.gz: ebc79caba4f53280dbf1dffa76ba9268ecbd6ae9634fd463f1920770a02531f0d5cd350a26ecbc439accf57fbe96d824e76349ce29492075fb2d4151b40cd46a
7
+ data.tar.gz: 79fa51828475fac62b1a5e4ec4562eb9b563da24760f85c41c42f123bdb3e882124a38686050a52c0c6b3ffa29577eaa547405e78ef14ad1b6b99f7fff5df0e8
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.3.0] - 2024-12-18
4
+
5
+ - Set up app space via terraform, with proper restricted egress security group
6
+ - Create rails_template18f:public_egress generator for integrating with cg-egress-proxy
7
+ - [Use exec when starting rails server](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#start-commands:~:text=To%20resolve%20this,process.%20For%20example%3A)
8
+ - Upgrade the i18n-js integration to 4.x
9
+
3
10
  ## [1.2.0] - 2024-09-20
4
11
 
5
12
  - new applications are now on Rails 7.2.x
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rails_template_18f (1.2.0)
4
+ rails_template_18f (1.3.0)
5
5
  activesupport (~> 7.2.0)
6
6
  colorize (~> 1.1)
7
7
  railties (~> 7.2.0)
@@ -10,9 +10,9 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- actionpack (7.2.0)
14
- actionview (= 7.2.0)
15
- activesupport (= 7.2.0)
13
+ actionpack (7.2.1)
14
+ actionview (= 7.2.1)
15
+ activesupport (= 7.2.1)
16
16
  nokogiri (>= 1.8.5)
17
17
  racc
18
18
  rack (>= 2.2.4, < 3.2)
@@ -21,13 +21,13 @@ GEM
21
21
  rails-dom-testing (~> 2.2)
22
22
  rails-html-sanitizer (~> 1.6)
23
23
  useragent (~> 0.16)
24
- actionview (7.2.0)
25
- activesupport (= 7.2.0)
24
+ actionview (7.2.1)
25
+ activesupport (= 7.2.1)
26
26
  builder (~> 3.1)
27
27
  erubi (~> 1.11)
28
28
  rails-dom-testing (~> 2.2)
29
29
  rails-html-sanitizer (~> 1.6)
30
- activesupport (7.2.0)
30
+ activesupport (7.2.1)
31
31
  base64
32
32
  bigdecimal
33
33
  concurrent-ruby (~> 1.0, >= 1.3.1)
@@ -54,16 +54,16 @@ GEM
54
54
  diff-lcs (1.5.1)
55
55
  drb (2.2.1)
56
56
  erubi (1.13.0)
57
- i18n (1.14.5)
57
+ i18n (1.14.6)
58
58
  concurrent-ruby (~> 1.0)
59
59
  io-console (0.7.2)
60
- irb (1.14.0)
60
+ irb (1.14.1)
61
61
  rdoc (>= 4.0.0)
62
62
  reline (>= 0.4.2)
63
63
  json (2.7.2)
64
64
  language_server-protocol (3.17.0.3)
65
65
  lint_roller (1.1.0)
66
- logger (1.6.0)
66
+ logger (1.6.1)
67
67
  loofah (2.22.0)
68
68
  crass (~> 1.0.2)
69
69
  nokogiri (>= 1.12.0)
@@ -75,7 +75,7 @@ GEM
75
75
  nokogiri (1.16.7-x86_64-linux)
76
76
  racc (~> 1.4)
77
77
  parallel (1.26.3)
78
- parser (3.3.4.2)
78
+ parser (3.3.5.0)
79
79
  ast (~> 2.4.1)
80
80
  racc
81
81
  psych (5.1.2)
@@ -96,9 +96,9 @@ GEM
96
96
  rails-html-sanitizer (1.6.0)
97
97
  loofah (~> 2.21)
98
98
  nokogiri (~> 1.14)
99
- railties (7.2.0)
100
- actionpack (= 7.2.0)
101
- activesupport (= 7.2.0)
99
+ railties (7.2.1)
100
+ actionpack (= 7.2.1)
101
+ activesupport (= 7.2.1)
102
102
  irb (~> 1.13)
103
103
  rackup (>= 1.0.0)
104
104
  rake (>= 12.2)
@@ -109,26 +109,25 @@ GEM
109
109
  rdoc (6.7.0)
110
110
  psych (>= 4.0.0)
111
111
  regexp_parser (2.9.2)
112
- reline (0.5.9)
112
+ reline (0.5.10)
113
113
  io-console (~> 0.5)
114
- rexml (3.3.6)
115
- strscan
114
+ rexml (3.3.8)
116
115
  rspec (3.13.0)
117
116
  rspec-core (~> 3.13.0)
118
117
  rspec-expectations (~> 3.13.0)
119
118
  rspec-mocks (~> 3.13.0)
120
- rspec-core (3.13.0)
119
+ rspec-core (3.13.1)
121
120
  rspec-support (~> 3.13.0)
122
- rspec-expectations (3.13.2)
121
+ rspec-expectations (3.13.3)
123
122
  diff-lcs (>= 1.2.0, < 2.0)
124
123
  rspec-support (~> 3.13.0)
125
- rspec-mocks (3.13.1)
124
+ rspec-mocks (3.13.2)
126
125
  diff-lcs (>= 1.2.0, < 2.0)
127
126
  rspec-support (~> 3.13.0)
128
- rspec-rails (6.1.4)
129
- actionpack (>= 6.1)
130
- activesupport (>= 6.1)
131
- railties (>= 6.1)
127
+ rspec-rails (7.0.1)
128
+ actionpack (>= 7.0)
129
+ activesupport (>= 7.0)
130
+ railties (>= 7.0)
132
131
  rspec-core (~> 3.13)
133
132
  rspec-expectations (~> 3.13)
134
133
  rspec-mocks (~> 3.13)
@@ -145,14 +144,14 @@ GEM
145
144
  rubocop-ast (>= 1.31.1, < 2.0)
146
145
  ruby-progressbar (~> 1.7)
147
146
  unicode-display_width (>= 2.4.0, < 3.0)
148
- rubocop-ast (1.32.1)
147
+ rubocop-ast (1.32.3)
149
148
  parser (>= 3.3.1.0)
150
149
  rubocop-performance (1.21.1)
151
150
  rubocop (>= 1.48.1, < 2.0)
152
151
  rubocop-ast (>= 1.31.1, < 2.0)
153
152
  ruby-progressbar (1.13.0)
154
153
  securerandom (0.3.1)
155
- standard (1.40.0)
154
+ standard (1.40.1)
156
155
  language_server-protocol (~> 3.17.0.2)
157
156
  lint_roller (~> 1.0)
158
157
  rubocop (~> 1.65.0)
@@ -165,14 +164,13 @@ GEM
165
164
  lint_roller (~> 1.1)
166
165
  rubocop-performance (~> 1.21.0)
167
166
  stringio (3.1.1)
168
- strscan (3.1.0)
169
- thor (1.3.1)
167
+ thor (1.3.2)
170
168
  tzinfo (2.0.6)
171
169
  concurrent-ruby (~> 1.0)
172
- unicode-display_width (2.5.0)
170
+ unicode-display_width (2.6.0)
173
171
  useragent (0.16.10)
174
- webrick (1.8.1)
175
- zeitwerk (2.6.17)
172
+ webrick (1.8.2)
173
+ zeitwerk (2.6.18)
176
174
 
177
175
  PLATFORMS
178
176
  arm64-darwin-23
@@ -71,6 +71,11 @@ commands:
71
71
  -p ${<< parameters.cloudgov_password >>} \
72
72
  -o << parameters.cloudgov_org >> \
73
73
  -s << parameters.cloudgov_space >>
74
+ - run:
75
+ name: Set restricted egress
76
+ command: |
77
+ cf bind-security-group trusted_local_networks_egress << parameters.cloudgov_org >> \
78
+ --space << parameters.cloudgov_space >>
74
79
  - run:
75
80
  name: Push application with deployment vars
76
81
  command: |
@@ -32,6 +32,14 @@ jobs:
32
32
  access_key=${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
33
33
  secret_key=${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
34
34
  <% end %>
35
+ - name: Set restricted egress
36
+ uses: cloud-gov/cg-cli-tools@main
37
+ with:
38
+ cf_username: ${{ secrets.CF_USERNAME }}
39
+ cf_password: ${{ secrets.CF_PASSWORD }}
40
+ cf_org: <%= cloud_gov_organization %>
41
+ cf_space: <%= cloud_gov_production_space %>
42
+ cf_command: bind-security-group trusted_local_networks_egress $INPUT_CF_ORG --space $INPUT_CF_SPACE
35
43
  - name: Deploy app
36
44
  uses: cloud-gov/cg-cli-tools@main
37
45
  with:
@@ -32,6 +32,14 @@ jobs:
32
32
  access_key=${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
33
33
  secret_key=${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
34
34
  <% end %>
35
+ - name: Set restricted egress
36
+ uses: cloud-gov/cg-cli-tools@main
37
+ with:
38
+ cf_username: ${{ secrets.CF_USERNAME }}
39
+ cf_password: ${{ secrets.CF_PASSWORD }}
40
+ cf_org: <%= cloud_gov_organization %>
41
+ cf_space: <%= cloud_gov_staging_space %>
42
+ cf_command: bind-security-group trusted_local_networks_egress $INPUT_CF_ORG --space $INPUT_CF_SPACE
35
43
  - name: Deploy app
36
44
  uses: cloud-gov/cg-cli-tools@main
37
45
  with:
@@ -12,37 +12,29 @@ module RailsTemplate18f
12
12
  Install and configure i18n-js gem to provide translations to JS code.
13
13
 
14
14
  By default, will only export translations with keys that match `*.js.*`
15
+
16
+ To use, add the following to your js code:
17
+
18
+ 1. `import { i18n } from './i18n';`
19
+ 2. `i18n.t('path.to.translation.key')`
15
20
  DESC
16
21
 
17
- def install_gem_and_tasks
18
- return if gem_installed?("i18n-js")
19
- gem "i18n-js", "~> 3.9"
22
+ def install_gems
23
+ gem "i18n-js", "~> 4.2" unless gem_installed?("i18n-js")
24
+ gem "listen", "~> 3.9", group: :development unless gem_installed?("listen")
20
25
  bundle_install do
21
26
  run "yarn add i18n-js"
22
- generate "i18n:js:config"
23
27
  end
24
28
  end
25
29
 
26
30
  def configure_translation_yaml
27
- append_to_file "config/i18n-js.yml", <<~EOYAML
28
- # remove `only` to include all translations
29
- translations:
30
- - file: "app/assets/builds/translations.js"
31
- only: "*.js.*"
32
- EOYAML
31
+ copy_file "config/i18n-js.yml"
33
32
  end
34
33
 
35
34
  def configure_asset_pipeline
36
35
  copy_file "lib/tasks/i18n.rake"
37
- environment "config.middleware.use I18n::JS::Middleware", env: :development
38
- insert_into_file "app/views/layouts/application.html.erb", indent(<<~EOHTML, 4), after: /<%= stylesheet_link_tag "application".*$\n/
39
- <%= javascript_include_tag "i18n", "data-turbo-track": "reload" %>
40
- <%= javascript_include_tag "translations", "data-turbo-track": "reload" %>
41
- EOHTML
42
- append_to_file "app/assets/config/manifest.js", <<~EOJS
43
- //= link i18n.js
44
- //= link translations.js
45
- EOJS
36
+ copy_file "config/initializers/i18n_js.rb"
37
+ copy_file "app/javascript/i18n.js"
46
38
  end
47
39
 
48
40
  def ignore_generated_file
@@ -50,7 +42,7 @@ module RailsTemplate18f
50
42
  append_to_file ".gitignore", <<~EOM
51
43
 
52
44
  # Generated by i18n-js
53
- /public/javascripts/i18n.js
45
+ /app/javascript/generated
54
46
  EOM
55
47
  end
56
48
  end
@@ -0,0 +1,11 @@
1
+ import { I18n } from 'i18n-js';
2
+ import translations from './generated/translations.json';
3
+
4
+ const userLocale = document.documentElement.lang;
5
+
6
+ export const i18n = new I18n();
7
+
8
+ i18n.store(translations);
9
+ i18n.defaultLocale = "en";
10
+ i18n.enableFallback = true;
11
+ i18n.locale = userLocale;
@@ -0,0 +1,4 @@
1
+ translations:
2
+ - file: "app/javascript/generated/translations.json"
3
+ patterns:
4
+ - "*.js.*"
@@ -0,0 +1,5 @@
1
+ Rails.application.config.after_initialize do
2
+ require "i18n-js/listen"
3
+ # This will only run in development
4
+ I18nJS.listen config_file: Rails.root.join("config/i18n-js.yml")
5
+ end
@@ -1,9 +1,10 @@
1
1
  # export translations as part of asset precompile
2
-
3
- Rake::Task["assets:precompile"].enhance(["i18n:js:export"])
4
-
5
- if Rake::Task.task_defined?("test:prepare")
6
- Rake::Task["test:prepare"].enhance(["i18n:js:export"])
7
- elsif Rake::Task.task_defined?("db:test:prepare")
8
- Rake::Task["db:test:prepare"].enhance(["i18n:js:export"])
2
+ namespace "i18n:js" do
3
+ desc "Call the i18n-js export method"
4
+ task :export do
5
+ require "i18n-js"
6
+ I18nJS.call(config_file: "config/i18n-js.yml")
7
+ end
9
8
  end
9
+
10
+ Rake::Task["javascript:build"].enhance(["i18n:js:export"])
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+ require "colorize"
5
+
6
+ module RailsTemplate18f
7
+ module Generators
8
+ class PublicEgressGenerator < ::Rails::Generators::Base
9
+ include Base
10
+ include CloudGovParsing
11
+
12
+ desc <<~DESC
13
+ Description:
14
+ Install files for running cg-egress-proxy in <env>-egress cloud.gov spaces
15
+ Prerequisite: the terraform generator has been run already
16
+ DESC
17
+
18
+ def check_terraform_exists
19
+ unless terraform_dir_exists?
20
+ fail "Run `rails g rails_template18f:terraform` before running this generator"
21
+ end
22
+ end
23
+
24
+ def use_terraform_module
25
+ append_to_file file_path("terraform/staging/main.tf"), terraform_module
26
+ append_to_file file_path("terraform/production/main.tf"), terraform_module
27
+ end
28
+
29
+ def add_to_deploy_steps
30
+ if file_exists?(".github/workflows/deploy-staging.yml")
31
+ insert_into_file ".github/workflows/deploy-staging.yml", <<EOD, before: " - name: Deploy app"
32
+ - name: Set public egress
33
+ uses: cloud-gov/cg-cli-tools@main
34
+ with:
35
+ cf_username: ${{ secrets.CF_USERNAME }}
36
+ cf_password: ${{ secrets.CF_PASSWORD }}
37
+ cf_org: #{cloud_gov_organization}
38
+ cf_space: #{cloud_gov_staging_space}-egress
39
+ cf_command: bind-security-group public_networks_egress $INPUT_CF_ORG --space $INPUT_CF_SPACE
40
+ EOD
41
+ end
42
+ if file_exists?(".github/workflows/deploy-production.yml")
43
+ insert_into_file ".github/workflows/deploy-production.yml", <<EOD, before: " - name: Deploy app"
44
+ - name: Set public egress
45
+ uses: cloud-gov/cg-cli-tools@main
46
+ with:
47
+ cf_username: ${{ secrets.CF_USERNAME }}
48
+ cf_password: ${{ secrets.CF_PASSWORD }}
49
+ cf_org: #{cloud_gov_organization}
50
+ cf_space: #{cloud_gov_production_space}-egress
51
+ cf_command: bind-security-group public_networks_egress $INPUT_CF_ORG --space $INPUT_CF_SPACE
52
+ EOD
53
+ end
54
+ if file_exists?(".circleci/config.yml")
55
+ insert_into_file ".circleci/config.yml", <<EOD, before: " name: Push application with deployment vars"
56
+ name: Set public egress
57
+ command: |
58
+ cf bind-security-group public_networks_egress << parameters.cloudgov_org >> \
59
+ --space << parameters.cloudgov_space >>-egress
60
+ - run:
61
+ EOD
62
+ end
63
+ end
64
+
65
+ def update_readme
66
+ insert_into_file "README.md", readme_content, before: "## Documentation"
67
+ end
68
+
69
+ def update_boundary_diagram
70
+ boundary_filename = "doc/compliance/apps/application.boundary.md"
71
+ insert_into_file boundary_filename, <<EOB, after: "System_Boundary(inventory, \"Application\") {\n"
72
+ Boundary(restricted_space, "Restricted egress space") {
73
+ }
74
+ Boundary(egress_space, "Public egress space") {
75
+ Container(proxy, "<&layers> Egress Proxy", "Caddy, cg-egress-proxy", "Proxy with allow-list of external connections")
76
+ }
77
+ EOB
78
+ insert_into_file boundary_filename, <<~EOB, before: "@enduml"
79
+ Rel(app, proxy, "Proxy outbound connections", "https (443)")
80
+ EOB
81
+ puts "\n ================ TODO ================ \n".yellow
82
+ puts "Update your application boundary to:"
83
+ puts "1. Place application and services within the Restricted egress space"
84
+ puts "2. Connect outbound connections through the egress proxy"
85
+ end
86
+
87
+ def update_oscal_doc
88
+ copy_remote_oscal_component "cg-egress-proxy", "https://raw.githubusercontent.com/GSA-TTS/cg-egress-proxy/refs/heads/main/docs/compliance/component-definitions/cg-egress-proxy/component-definition.json"
89
+ end
90
+
91
+ no_tasks do
92
+ def readme_content
93
+ <<~README
94
+ ### Public Egress Proxy
95
+
96
+ 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
97
+ reach should be added to the `allowlist` terraform configuration in `terraform/staging/main.tf` and `terraform/production/main.tf`
98
+
99
+ 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.
100
+ README
101
+ end
102
+
103
+ def terraform_module
104
+ <<~EOT
105
+
106
+ module "egress_space" {
107
+ source = "github.com/gsa-tts/terraform-cloudgov//cg_space?ref=v1.1.0"
108
+
109
+ cf_org_name = local.cf_org_name
110
+ cf_space_name = "${local.cf_space_name}-egress"
111
+ # deployers should include any user or service account ID that will deploy the egress proxy
112
+ deployers = [
113
+ var.cf_user
114
+ ]
115
+ }
116
+
117
+ module "egress_proxy" {
118
+ source = "github.com/gsa-tts/terraform-cloudgov//egress_proxy?ref=v1.1.0"
119
+
120
+ cf_org_name = local.cf_org_name
121
+ cf_space_name = module.egress_space.space_name
122
+ client_space = local.cf_space_name
123
+ name = "egress-proxy-${local.env}"
124
+ # comment out allowlist if this module is being deployed before the app has ever been deployed
125
+ allowlist = {
126
+ "${local.app_name}-${local.env}" = []
127
+ }
128
+ # depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
129
+ depends_on = [module.app_space, module.egress_space]
130
+ }
131
+ EOT
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -64,7 +64,7 @@ These steps are run once per project.
64
64
  A [SpaceDeployer](https://cloud.gov/docs/services/cloud-gov-service-account/) account is required to run terraform or
65
65
  deploy the application from the CI/CD pipeline. Create a new account by running:
66
66
 
67
- `../bin/ops/create_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME>`
67
+ `../bin/ops/create_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME> -m`
68
68
 
69
69
  ## Set up a new environment manually
70
70
 
@@ -80,7 +80,7 @@ The below steps rely on you first configuring access to the Terraform state in s
80
80
  # something that communicates the purpose of the deployer
81
81
  # for example: circleci-deployer for the credentials CircleCI uses to
82
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> > secrets.auto.tfvars
83
+ ../../bin/ops/create_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME> -m > secrets.auto.tfvars
84
84
  ```
85
85
 
86
86
  The script will output the `username` (as `cf_user`) and `password` (as `cf_password`) for your `<ACCOUNT_NAME>`. Read more in the [cloud.gov service account documentation](https://cloud.gov/docs/services/cloud-gov-service-account/).
@@ -6,7 +6,7 @@ module "s3" {
6
6
  source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v1.0.0"
7
7
 
8
8
  cf_org_name = "<%= cloud_gov_organization %>"
9
- cf_space_name = "<%= cloud_gov_production_space %>"
9
+ cf_space_name = "<%= cloud_gov_production_space %>-mgmt"
10
10
  name = local.s3_service_name<% if cloud_gov_organization == "sandbox-gsa" %>
11
11
  s3_plan_name = "basic-sandbox"<% end %>
12
12
  }
@@ -16,7 +16,8 @@ dig_output () {
16
16
  }
17
17
 
18
18
  if [[ ! -f "secrets.auto.tfvars" ]]; then
19
- ../../bin/ops/create_service_account.sh -s <%= cloud_gov_production_space %> -u config-bootstrap-deployer > secrets.auto.tfvars
19
+ cf target -s <%= cloud_gov_production_space %>-mgmt || cf create-space <%= cloud_gov_production_space %>-mgmt && cf disallow-space-ssh <%= cloud_gov_production_space %>-mgmt
20
+ ../../bin/ops/create_service_account.sh -s <%= cloud_gov_production_space %>-mgmt -u config-bootstrap-deployer > secrets.auto.tfvars
20
21
  fi
21
22
 
22
23
  if [[ $# -gt 0 ]]; then
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
- ../../bin/ops/destroy_service_account.sh -s <%= cloud_gov_production_space %> -u config-bootstrap-deployer
3
+ ../../bin/ops/destroy_service_account.sh -s <%= cloud_gov_production_space %>-mgmt -u config-bootstrap-deployer
4
4
 
5
5
  rm secrets.auto.tfvars
@@ -5,32 +5,48 @@ locals {
5
5
  app_name = "<%= app_name %>"
6
6
  }
7
7
 
8
+ module "app_space" {
9
+ source = "github.com/gsa-tts/terraform-cloudgov//cg_space?ref=v1.1.0"
10
+
11
+ cf_org_name = local.cf_org_name
12
+ cf_space_name = local.cf_space_name
13
+ deployers = [var.cf_user]
14
+ # developers should include any users that will potentially need to run `cf ssh` on the app
15
+ developers = []
16
+ }
17
+
8
18
  module "database" {
9
- source = "github.com/gsa-tts/terraform-cloudgov//database?ref=v1.0.0"
19
+ source = "github.com/gsa-tts/terraform-cloudgov//database?ref=v1.1.0"
10
20
 
11
21
  cf_org_name = local.cf_org_name
12
22
  cf_space_name = local.cf_space_name
13
23
  name = "${local.app_name}-rds-${local.env}"
14
24
  rds_plan_name = "TKTK-production-rds-plan"
25
+ # depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
26
+ depends_on = [module.app_space]
15
27
  }
16
28
  <% if has_active_job? %>
17
29
  module "redis" {
18
- source = "github.com/gsa-tts/terraform-cloudgov//redis?ref=v1.0.0"
30
+ source = "github.com/gsa-tts/terraform-cloudgov//redis?ref=v1.1.0"
19
31
 
20
32
  cf_org_name = local.cf_org_name
21
33
  cf_space_name = local.cf_space_name
22
34
  name = "${local.app_name}-redis-${local.env}"
23
35
  redis_plan_name = "TKTK-production-redis-plan"
36
+ # depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
37
+ depends_on = [module.app_space]
24
38
  }
25
39
  <% end %>
26
40
  <% if has_active_storage? %>
27
41
  module "s3" {
28
- source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v1.0.0"
42
+ source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v1.1.0"
29
43
 
30
44
  cf_org_name = local.cf_org_name
31
45
  cf_space_name = local.cf_space_name
32
46
  name = "${local.app_name}-s3-${local.env}"<% if cloud_gov_organization == "sandbox-gsa" %>
33
47
  s3_plan_name = "basic-sandbox"<% end %>
48
+ # depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
49
+ depends_on = [module.app_space]
34
50
  }
35
51
 
36
52
  ###########################################################################
@@ -40,7 +56,7 @@ module "s3" {
40
56
  # 2) Your organization has sufficient memory. Each clamav app requires 3GB
41
57
  ###########################################################################
42
58
  # module "clamav" {
43
- # source = "github.com/gsa-tts/terraform-cloudgov//clamav?ref=v1.0.0"
59
+ # source = "github.com/gsa-tts/terraform-cloudgov//clamav?ref=v1.1.0"
44
60
  #
45
61
  # cf_org_name = local.cf_org_name
46
62
  # cf_space_name = local.cf_space_name
@@ -48,6 +64,8 @@ module "s3" {
48
64
  # name = "${local.app_name}-clamapi-${local.env}"
49
65
  # clamav_image = "ghcr.io/gsa-tts/clamav-rest/clamav:20240602"
50
66
  # max_file_size = "30M"
67
+ # # depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
68
+ # depends_on = [module.app_space]
51
69
  # }
52
70
  <% end %>
53
71
 
@@ -59,7 +77,7 @@ module "s3" {
59
77
  # `cf create-domain <%= cloud_gov_organization %> TKTK-production-domain-name`
60
78
  ###########################################################################
61
79
  # module "domain" {
62
- # source = "github.com/gsa-tts/terraform-cloudgov//domain?ref=v1.0.0"
80
+ # source = "github.com/gsa-tts/terraform-cloudgov//domain?ref=v1.1.0"
63
81
  #
64
82
  # cf_org_name = local.cf_org_name
65
83
  # cf_space_name = local.cf_space_name
@@ -67,4 +85,6 @@ module "s3" {
67
85
  # cdn_plan_name = "domain"
68
86
  # domain_name = "TKTK-production-domain-name"
69
87
  # host_name = "TKTK-production-hostname (optional)"
88
+ # # depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
89
+ # depends_on = [module.app_space]
70
90
  # }
@@ -5,32 +5,48 @@ locals {
5
5
  app_name = "<%= app_name %>"
6
6
  }
7
7
 
8
+ module "app_space" {
9
+ source = "github.com/gsa-tts/terraform-cloudgov//cg_space?ref=v1.1.0"
10
+
11
+ cf_org_name = local.cf_org_name
12
+ cf_space_name = local.cf_space_name
13
+ deployers = [var.cf_user]
14
+ # developers should include any users that will potentially need to run `cf ssh` on the app
15
+ developers = []
16
+ }
17
+
8
18
  module "database" {
9
- source = "github.com/gsa-tts/terraform-cloudgov//database?ref=v1.0.0"
19
+ source = "github.com/gsa-tts/terraform-cloudgov//database?ref=v1.1.0"
10
20
 
11
21
  cf_org_name = local.cf_org_name
12
22
  cf_space_name = local.cf_space_name
13
23
  name = "${local.app_name}-rds-${local.env}"
14
24
  rds_plan_name = "micro-psql"
25
+ # depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
26
+ depends_on = [module.app_space]
15
27
  }
16
28
  <% if has_active_job? %>
17
29
  module "redis" {
18
- source = "github.com/gsa-tts/terraform-cloudgov//redis?ref=v1.0.0"
30
+ source = "github.com/gsa-tts/terraform-cloudgov//redis?ref=v1.1.0"
19
31
 
20
32
  cf_org_name = local.cf_org_name
21
33
  cf_space_name = local.cf_space_name
22
34
  name = "${local.app_name}-redis-${local.env}"
23
35
  redis_plan_name = "redis-dev"
36
+ # depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
37
+ depends_on = [module.app_space]
24
38
  }
25
39
  <% end %>
26
40
  <% if has_active_storage? %>
27
41
  module "s3" {
28
- source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v1.0.0"
42
+ source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v1.1.0"
29
43
 
30
44
  cf_org_name = local.cf_org_name
31
45
  cf_space_name = local.cf_space_name
32
46
  name = "${local.app_name}-s3-${local.env}"<% if cloud_gov_organization == "sandbox-gsa" %>
33
47
  s3_plan_name = "basic-sandbox"<% end %>
48
+ # depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
49
+ depends_on = [module.app_space]
34
50
  }
35
51
 
36
52
  ###########################################################################
@@ -40,7 +56,7 @@ module "s3" {
40
56
  # 2) Your organization has sufficient memory. Each clamav app requires 3GB
41
57
  ###########################################################################
42
58
  # module "clamav" {
43
- # source = "github.com/gsa-tts/terraform-cloudgov//clamav?ref=v1.0.0"
59
+ # source = "github.com/gsa-tts/terraform-cloudgov//clamav?ref=v1.1.0"
44
60
  #
45
61
  # cf_org_name = local.cf_org_name
46
62
  # cf_space_name = local.cf_space_name
@@ -48,5 +64,7 @@ module "s3" {
48
64
  # name = "${local.app_name}-clamapi-${local.env}"
49
65
  # clamav_image = "ghcr.io/gsa-tts/clamav-rest/clamav:20240602"
50
66
  # max_file_size = "30M"
67
+ # # depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
68
+ # depends_on = [module.app_space]
51
69
  # }
52
70
  <% end %>
@@ -59,6 +59,13 @@ module RailsTemplate18f
59
59
  Dir.exist? file_path("doc/compliance/oscal")
60
60
  end
61
61
 
62
+ def copy_remote_oscal_component(component_name, cd_url)
63
+ get cd_url, File.join(oscal_component_path, component_name, "component-definition.json")
64
+ if oscal_dir_exists?
65
+ insert_into_file "doc/compliance/oscal/trestle-config.yaml", " - #{component_name}\n"
66
+ end
67
+ end
68
+
62
69
  def copy_oscal_component(component_name)
63
70
  template "oscal/component-definitions/#{component_name}/component-definition.json",
64
71
  File.join(oscal_component_path, component_name, "component-definition.json")
@@ -4,6 +4,7 @@ module RailsTemplate18f
4
4
  module Generators
5
5
  module CloudGovOptions
6
6
  extend ActiveSupport::Concern
7
+ include CloudGovParsing
7
8
 
8
9
  included do
9
10
  class_option :cg_org, desc: "cloud.gov organization name"
@@ -14,39 +15,18 @@ module RailsTemplate18f
14
15
  private
15
16
 
16
17
  def cloud_gov_organization
17
- if options[:cg_org].present?
18
- return options[:cg_org]
19
- elsif terraform_dir_exists?
20
- staging_main = file_content("terraform/staging/main.tf")
21
- if (matches = staging_main.match(/cf_org_name\s+= "(?<org_name>.*)"/))
22
- return matches[:org_name]
23
- end
24
- end
25
- "TKTK-cloud.gov-org-name"
18
+ return options[:cg_org] if options[:cg_org].present?
19
+ super
26
20
  end
27
21
 
28
22
  def cloud_gov_staging_space
29
- if options[:cg_staging].present?
30
- return options[:cg_staging]
31
- elsif terraform_dir_exists?
32
- staging_main = file_content("terraform/staging/main.tf")
33
- if (matches = staging_main.match(/cf_space_name\s+= "(?<space_name>.*)"/))
34
- return matches[:space_name]
35
- end
36
- end
37
- "staging"
23
+ return options[:cg_staging] if options[:cg_staging].present?
24
+ super
38
25
  end
39
26
 
40
27
  def cloud_gov_production_space
41
- if options[:cg_prod].present?
42
- return options[:cg_prod]
43
- elsif terraform_dir_exists?
44
- prod_main = file_content("terraform/production/main.tf")
45
- if (matches = prod_main.match(/cf_space_name\s+= "(?<space_name>.*)"/))
46
- return matches[:space_name]
47
- end
48
- end
49
- "prod"
28
+ return options[:cg_prod] if options[:cg_prod].present?
29
+ super
50
30
  end
51
31
  end
52
32
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsTemplate18f
4
+ module Generators
5
+ module CloudGovParsing
6
+ extend ActiveSupport::Concern
7
+
8
+ private
9
+
10
+ def cloud_gov_organization
11
+ if terraform_dir_exists?
12
+ staging_main = file_content("terraform/staging/main.tf")
13
+ if (matches = staging_main.match(/cf_org_name\s+= "(?<org_name>.*)"/))
14
+ return matches[:org_name]
15
+ end
16
+ end
17
+ "TKTK-cloud.gov-org-name"
18
+ end
19
+
20
+ def cloud_gov_staging_space
21
+ if terraform_dir_exists?
22
+ staging_main = file_content("terraform/staging/main.tf")
23
+ if (matches = staging_main.match(/cf_space_name\s+= "(?<space_name>.*)"/))
24
+ return matches[:space_name]
25
+ end
26
+ end
27
+ "staging"
28
+ end
29
+
30
+ def cloud_gov_production_space
31
+ if terraform_dir_exists?
32
+ prod_main = file_content("terraform/production/main.tf")
33
+ if (matches = prod_main.match(/cf_space_name\s+= "(?<space_name>.*)"/))
34
+ return matches[:space_name]
35
+ end
36
+ end
37
+ "prod"
38
+ end
39
+ end
40
+ end
41
+ end
@@ -6,6 +6,7 @@ module RailsTemplate18f
6
6
 
7
7
  autoload :Base
8
8
  autoload :CloudGovOptions
9
+ autoload :CloudGovParsing
9
10
  autoload :PipelineOptions
10
11
  end
11
12
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsTemplate18f
4
- VERSION = "1.2.0"
4
+ VERSION = "1.3.0"
5
5
  end
@@ -7,14 +7,18 @@ $0: Create a Service User Account for a given space
7
7
 
8
8
  Usage:
9
9
  $0 -h
10
- $0 -s <SPACE NAME> -u <USER NAME> [-r <ROLE NAME>] [-o <ORG NAME>]
10
+ $0 -s <SPACE NAME> -u <USER NAME> [-r <ROLE NAME>] [-o <ORG NAME>] [-m]
11
11
 
12
12
  Options:
13
13
  -h: show help and exit
14
14
  -s <SPACE NAME>: configure the space to act on. Required
15
15
  -u <USER NAME>: set the service user name. Required
16
16
  -r <ROLE NAME>: set the service user's role to either space-deployer or space-auditor. Default: space-deployer
17
+ -m: If provided, make the service user an OrgManager
17
18
  -o <ORG NAME>: configure the organization to act on. Default: $org
19
+
20
+ Notes:
21
+ * OrgManager is required for terraform to create <env>-egress spaces
18
22
  "
19
23
 
20
24
  set -e
@@ -23,8 +27,9 @@ set -o pipefail
23
27
  space=""
24
28
  service=""
25
29
  role="space-deployer"
30
+ org_manager="false"
26
31
 
27
- while getopts ":hs:u:r:o:" opt; do
32
+ while getopts ":hms:u:r:o:" opt; do
28
33
  case "$opt" in
29
34
  s)
30
35
  space=${OPTARG}
@@ -38,6 +43,9 @@ while getopts ":hs:u:r:o:" opt; do
38
43
  o)
39
44
  org=${OPTARG}
40
45
  ;;
46
+ m)
47
+ org_manager="true"
48
+ ;;
41
49
  h)
42
50
  echo "$usage"
43
51
  exit 0
@@ -69,6 +77,10 @@ creds=`cf service-key $service service-account-key | tail -n +2 | jq '.credentia
69
77
  username=`echo $creds | jq -r '.username'`
70
78
  password=`echo $creds | jq -r '.password'`
71
79
 
80
+ if [[ "$org_manager" = "true" ]]; then
81
+ cf set-org-role $username $org OrgManager 1>&2
82
+ fi
83
+
72
84
  cat << EOF
73
85
  # generated with $0 -s $space -u $service -r $role -o $org
74
86
  # revoke with $(dirname $0)/destroy_service_account.sh -s $space -u $service -o $org
@@ -46,8 +46,5 @@ fi
46
46
 
47
47
  cf target -o $org -s $space
48
48
 
49
- # destroy service key
50
- cf delete-service-key $service service-account-key -f
51
-
52
49
  # destroy service
53
50
  cf delete-service $service -f
@@ -12,6 +12,6 @@ applications:
12
12
  - type: web
13
13
  instances: ((web_instances))
14
14
  memory: ((web_memory))
15
- command: bundle exec rake cf:on_first_instance db:migrate && bundle exec rails s -b 0.0.0.0 -p $PORT -e $RAILS_ENV
15
+ command: bundle exec rake cf:on_first_instance db:migrate && exec bundle exec rails s -b 0.0.0.0 -p $PORT -e $RAILS_ENV
16
16
  services:
17
17
  - <%= app_name %>-rds-((env))
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_template_18f
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Ahearn
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-09-20 00:00:00.000000000 Z
11
+ date: 2024-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -174,6 +174,9 @@ files:
174
174
  - lib/generators/rails_template18f/i18n/templates/config/locales/fr.yml
175
175
  - lib/generators/rails_template18f/i18n/templates/config/locales/zh.yml
176
176
  - lib/generators/rails_template18f/i18n_js/i18n_js_generator.rb
177
+ - lib/generators/rails_template18f/i18n_js/templates/app/javascript/i18n.js
178
+ - lib/generators/rails_template18f/i18n_js/templates/config/i18n-js.yml
179
+ - lib/generators/rails_template18f/i18n_js/templates/config/initializers/i18n_js.rb
177
180
  - lib/generators/rails_template18f/i18n_js/templates/lib/tasks/i18n.rake
178
181
  - lib/generators/rails_template18f/newrelic/newrelic_generator.rb
179
182
  - lib/generators/rails_template18f/newrelic/templates/config/newrelic.yml.tt
@@ -182,6 +185,7 @@ files:
182
185
  - lib/generators/rails_template18f/oscal/templates/bin/trestle.tt
183
186
  - lib/generators/rails_template18f/oscal/templates/doc/compliance/oscal/trestle-config.yaml.tt
184
187
  - lib/generators/rails_template18f/oscal/templates/github/actions/trestle-cmd/action.yml.tt
188
+ - lib/generators/rails_template18f/public_egress/public_egress_generator.rb
185
189
  - lib/generators/rails_template18f/rails_erd/rails_erd_generator.rb
186
190
  - lib/generators/rails_template18f/rails_erd/templates/erdconfig
187
191
  - lib/generators/rails_template18f/sidekiq/sidekiq_generator.rb
@@ -194,15 +198,16 @@ files:
194
198
  - lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/teardown_creds.sh.tt
195
199
  - lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/variables.tf
196
200
  - lib/generators/rails_template18f/terraform/templates/terraform/production/main.tf.tt
197
- - lib/generators/rails_template18f/terraform/templates/terraform/production/providers.tf.tt
201
+ - lib/generators/rails_template18f/terraform/templates/terraform/production/providers.tf
198
202
  - lib/generators/rails_template18f/terraform/templates/terraform/production/variables.tf
199
203
  - lib/generators/rails_template18f/terraform/templates/terraform/staging/main.tf.tt
200
- - lib/generators/rails_template18f/terraform/templates/terraform/staging/providers.tf.tt
204
+ - lib/generators/rails_template18f/terraform/templates/terraform/staging/providers.tf
201
205
  - lib/generators/rails_template18f/terraform/templates/terraform/staging/variables.tf
202
206
  - lib/generators/rails_template18f/terraform/terraform_generator.rb
203
207
  - lib/rails_template18f/generators.rb
204
208
  - lib/rails_template18f/generators/base.rb
205
209
  - lib/rails_template18f/generators/cloud_gov_options.rb
210
+ - lib/rails_template18f/generators/cloud_gov_parsing.rb
206
211
  - lib/rails_template18f/generators/pipeline_options.rb
207
212
  - lib/rails_template18f/version.rb
208
213
  - lib/rails_template_18f.rb