putpaws 0.1.3 → 0.1.5
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/README.md +38 -5
- data/lib/putpaws/code_build/project_command.rb +17 -0
- data/lib/putpaws/code_build/tasks/build_task.rake +16 -4
- data/lib/putpaws/provision/config_writer.rb +26 -9
- data/lib/putpaws/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6b0c08e32fd66d0f401c637c162bb7d2e408beb0110e433fec09d2a5853e0372
|
|
4
|
+
data.tar.gz: faeacb4b1476fd8247f627e32640ddaaac55e906754bba8e0155adc35a624225
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8f43a0329c4b6705b72c235687f0ba9f3a038a1314c32dca0dcfb83f26f28326b0e7ae7d2d1cb13267674626ccd47786100b574b17fa95119606ebcf960b1193
|
|
7
|
+
data.tar.gz: 3488ea35bc10ce0ed4449ed0ca1ec97836f22535d246662f3d3f729779fc12d1e67b5a231cc28acc7fa9c816c369a59a37e6f5a9d5bda45c97fa9e9e70fc0291
|
data/README.md
CHANGED
|
@@ -55,6 +55,14 @@ or a new one is created for the service when left empty on `ready`.
|
|
|
55
55
|
When the service step completes, the new service is reflected into
|
|
56
56
|
`.putpaws/application.json` and `.putpaws/infra.json` (diff is shown and confirmed),
|
|
57
57
|
so `ecs:attach`, `ecs:shell`, `ecs:run` and `log:*` work immediately.
|
|
58
|
+
One entry is written per task definition of the preset, keyed by the task definition
|
|
59
|
+
family `{service_name}-{suffix}` (Ex: `awesome-api-staging-app` / `awesome-api-staging-web`),
|
|
60
|
+
each pointing at the `infra.target` of the same name. Only the entry of the preset's
|
|
61
|
+
`service_task_definition` carries `service` (for `ecs:deploy` / `ecs:attach`); the others have
|
|
62
|
+
`service: null` and are meant for one-off tasks (`ecs:run` / `ecs:shell` / scheduler),
|
|
63
|
+
so `db:migrate` keeps running on the plain `app` task definition even when the service
|
|
64
|
+
runs `web` (nginx + app). `infra.network` is written once as `{service_name}`.
|
|
65
|
+
Existing keys are never deleted; remove stale ones by hand.
|
|
58
66
|
Secrets are handled by reference only: task definitions point to existing
|
|
59
67
|
SSM parameters (Ex: `/{service_name}/RAILS_MASTER_KEY`) and putpaws never touches the values.
|
|
60
68
|
|
|
@@ -182,6 +190,15 @@ so you can identify them on the AWS console and on the task list of `ecs:attach`
|
|
|
182
190
|
`ecs:run` and `ecs:shell` require `network` and `target` in `.putpaws/application.json`,
|
|
183
191
|
which refer to the `network` / `target` sections of `.putpaws/infra.json` (the same ones used by scheduler).
|
|
184
192
|
|
|
193
|
+
### CodeBuild
|
|
194
|
+
|
|
195
|
+
Start the CI build. By default it is fire-and-forget; pass `wait=true` to wait
|
|
196
|
+
until the build completes (phases are printed) and exit non-zero on failure.
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
bundle exec putpaws awesome-api-staging code_build:build branch=main wait=true
|
|
200
|
+
```
|
|
201
|
+
|
|
185
202
|
### CloudWatch Logs
|
|
186
203
|
|
|
187
204
|
`tail -f`
|
|
@@ -216,19 +233,35 @@ gem 'putpaws'
|
|
|
216
233
|
|
|
217
234
|
`.putpaws/application.json`
|
|
218
235
|
|
|
236
|
+
Keys are free-form names you pass to the CLI. The ones written by `putpaws up` follow
|
|
237
|
+
`{service_name}-{suffix}`: `-app` for one-off tasks (`service: null`), `-web` for the
|
|
238
|
+
long-running service.
|
|
239
|
+
|
|
219
240
|
```
|
|
220
241
|
{
|
|
221
|
-
"awesome-api-staging": {
|
|
242
|
+
"awesome-api-staging-app": {
|
|
222
243
|
"region": "ap-northeast-1",
|
|
223
244
|
"cluster": "cluster-staging",
|
|
224
245
|
"service": null,
|
|
225
|
-
"task_name_prefix": "awesome-api",
|
|
226
|
-
"log_group_prefix": "/ecs/awesome
|
|
246
|
+
"task_name_prefix": "awesome-api-staging-app",
|
|
247
|
+
"log_group_prefix": "/ecs/awesome-api-staging",
|
|
248
|
+
"log_region": null,
|
|
249
|
+
"build_log_group_prefix": "/aws/codebuild/awesome-api-staging",
|
|
250
|
+
"build_project_name_prefix": "awesome-api-staging",
|
|
251
|
+
"network": "awesome-api-staging",
|
|
252
|
+
"target": "awesome-api-staging-app"
|
|
253
|
+
},
|
|
254
|
+
"awesome-api-staging-web": {
|
|
255
|
+
"region": "ap-northeast-1",
|
|
256
|
+
"cluster": "cluster-staging",
|
|
257
|
+
"service": "awesome-api-staging",
|
|
258
|
+
"task_name_prefix": "awesome-api-staging-web",
|
|
259
|
+
"log_group_prefix": "/ecs/awesome-api-staging",
|
|
227
260
|
"log_region": null,
|
|
228
261
|
"build_log_group_prefix": "/aws/codebuild/awesome-api-staging",
|
|
229
262
|
"build_project_name_prefix": "awesome-api-staging",
|
|
230
|
-
"network": "awesome-
|
|
231
|
-
"target": "awesome-staging"
|
|
263
|
+
"network": "awesome-api-staging",
|
|
264
|
+
"target": "awesome-api-staging-web"
|
|
232
265
|
},
|
|
233
266
|
"awesome-api-production": {
|
|
234
267
|
"region": "ap-northeast-1",
|
|
@@ -41,6 +41,23 @@ module Putpaws::CodeBuild
|
|
|
41
41
|
codebuild_client.start_build(**params)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
def wait_until_build_complete(build_id, timeout: 3600, interval: 10)
|
|
45
|
+
deadline = Time.now + timeout
|
|
46
|
+
last_phase = nil
|
|
47
|
+
loop do
|
|
48
|
+
res = codebuild_client.batch_get_builds(ids: [build_id])
|
|
49
|
+
build = res.builds.first
|
|
50
|
+
raise "Build not found: #{build_id}" unless build
|
|
51
|
+
if build.current_phase != last_phase
|
|
52
|
+
last_phase = build.current_phase
|
|
53
|
+
puts " phase: #{last_phase}"
|
|
54
|
+
end
|
|
55
|
+
return build if build.build_status != 'IN_PROGRESS'
|
|
56
|
+
raise "Timed out waiting for build to complete: #{build_id}" if Time.now > deadline
|
|
57
|
+
sleep interval
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
44
61
|
def build_source_version(type:, version:)
|
|
45
62
|
type = type.to_sym
|
|
46
63
|
if type == :branch
|
|
@@ -15,7 +15,7 @@ namespace :code_build do
|
|
|
15
15
|
set :codebuild_project, codebuild_project
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
desc "Start build."
|
|
18
|
+
desc "Start build. Pass wait=true to wait until the build completes and fail on error. (Ex) branch=main wait=true"
|
|
19
19
|
task build: :set_project do
|
|
20
20
|
aws = Putpaws::CodeBuild::ProjectCommand.config(fetch(:app))
|
|
21
21
|
|
|
@@ -30,10 +30,22 @@ namespace :code_build do
|
|
|
30
30
|
end
|
|
31
31
|
codebuild_project = fetch(:codebuild_project)
|
|
32
32
|
aws.codebuild_project = codebuild_project
|
|
33
|
-
aws.start_build_with_specific_version(
|
|
34
|
-
source_version: source_version,
|
|
35
|
-
environment_variables: ENV['env'] ? JSON.parse(ENV['env']) : {},
|
|
33
|
+
res = aws.start_build_with_specific_version(
|
|
34
|
+
source_version: source_version,
|
|
35
|
+
environment_variables: ENV['env'] ? JSON.parse(ENV['env']) : {},
|
|
36
36
|
buildspec_override: ENV['buildspec']
|
|
37
37
|
)
|
|
38
|
+
build = res.build
|
|
39
|
+
puts "Build started: #{build.id}"
|
|
40
|
+
|
|
41
|
+
if ENV['wait']
|
|
42
|
+
puts "Waiting for the build to complete..."
|
|
43
|
+
build = aws.wait_until_build_complete(build.id)
|
|
44
|
+
if build.build_status == 'SUCCEEDED'
|
|
45
|
+
puts "Build succeeded: #{build.id}"
|
|
46
|
+
else
|
|
47
|
+
raise "Build #{build.build_status.downcase}: #{build.id}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
38
50
|
end
|
|
39
51
|
end
|
|
@@ -8,6 +8,15 @@ module Putpaws
|
|
|
8
8
|
# Reflects provisioned resources into .putpaws/application.json and
|
|
9
9
|
# .putpaws/infra.json. Only the keys of the target service are touched.
|
|
10
10
|
# Shows a diff and asks for confirmation before writing.
|
|
11
|
+
#
|
|
12
|
+
# One application entry and one infra.target entry are written per task
|
|
13
|
+
# definition of the preset, keyed by the task definition family
|
|
14
|
+
# (`<service_name>-<suffix>`). The entry whose suffix is the preset's
|
|
15
|
+
# `service_task_definition` carries `service` so that ecs:deploy /
|
|
16
|
+
# ecs:attach address the long-running service; the others are for
|
|
17
|
+
# one-off tasks (ecs:run / ecs:shell / scheduler) and have `service: null`.
|
|
18
|
+
# infra.network is written once per service as it does not depend on the
|
|
19
|
+
# task definition.
|
|
11
20
|
class ConfigWriter
|
|
12
21
|
attr_reader :config, :state, :prompt, :io
|
|
13
22
|
def initialize(config:, state:, prompt:, io: $stdout)
|
|
@@ -17,17 +26,18 @@ module Putpaws
|
|
|
17
26
|
@io = io
|
|
18
27
|
end
|
|
19
28
|
|
|
20
|
-
def application_entry
|
|
29
|
+
def application_entry(entry)
|
|
30
|
+
family = config.task_definition_family(entry[:suffix])
|
|
21
31
|
{
|
|
22
32
|
region: config.region,
|
|
23
33
|
cluster: config.cluster_name,
|
|
24
|
-
service: config.service_name,
|
|
25
|
-
task_name_prefix:
|
|
34
|
+
service: service_entry?(entry) ? config.service_name : nil,
|
|
35
|
+
task_name_prefix: family,
|
|
26
36
|
log_group_prefix: config.log_group,
|
|
27
37
|
build_log_group_prefix: config.build_log_group,
|
|
28
38
|
build_project_name_prefix: config.build_project_name,
|
|
29
39
|
network: config.service_name,
|
|
30
|
-
target:
|
|
40
|
+
target: family,
|
|
31
41
|
}
|
|
32
42
|
end
|
|
33
43
|
|
|
@@ -39,25 +49,32 @@ module Putpaws
|
|
|
39
49
|
}
|
|
40
50
|
end
|
|
41
51
|
|
|
42
|
-
def target_entry
|
|
52
|
+
def target_entry(entry)
|
|
43
53
|
{
|
|
44
54
|
# Used by EventBridge Scheduler (scheduler:deploy).
|
|
45
55
|
scheduler_role: config.roles[:scheduler_role_arn],
|
|
46
56
|
cluster: state.resources[:cluster_arn],
|
|
47
57
|
# Revision-less on purpose: always run the latest ACTIVE revision.
|
|
48
|
-
task_definition: config.
|
|
49
|
-
container_name:
|
|
58
|
+
task_definition: config.task_definition_family(entry[:suffix]),
|
|
59
|
+
container_name: entry[:container_name] || 'app',
|
|
50
60
|
}
|
|
51
61
|
end
|
|
52
62
|
|
|
53
63
|
def apply!
|
|
54
|
-
write_key(path('application.json'), [config.service_name.to_sym], application_entry)
|
|
55
64
|
write_key(path('infra.json'), [:network, config.service_name.to_sym], network_entry)
|
|
56
|
-
|
|
65
|
+
config.preset.task_definitions.each do |entry|
|
|
66
|
+
key = config.task_definition_family(entry[:suffix]).to_sym
|
|
67
|
+
write_key(path('application.json'), [key], application_entry(entry))
|
|
68
|
+
write_key(path('infra.json'), [:target, key], target_entry(entry))
|
|
69
|
+
end
|
|
57
70
|
end
|
|
58
71
|
|
|
59
72
|
private
|
|
60
73
|
|
|
74
|
+
def service_entry?(entry)
|
|
75
|
+
entry[:suffix] == config.preset.service_task_definition
|
|
76
|
+
end
|
|
77
|
+
|
|
61
78
|
def path(basename)
|
|
62
79
|
Pathname.new(config.path_prefix).join(basename)
|
|
63
80
|
end
|
data/lib/putpaws/version.rb
CHANGED