cai-ecs-entrypoint 1.1.0 → 2.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b95c711494fdbf456d3bee012a150a7fa86036c66d22b083b36d84e968861fbf
4
- data.tar.gz: 793012dc89512c79e649a1be18cf8f3a9d9f6800e1a6e874ed349ed124696af1
3
+ metadata.gz: fbe4644ac9f2ff239fe682cccfd12a3dbde20884e4be250dfe029a5534272abc
4
+ data.tar.gz: 92d49431371de60820973942f4f0811255f3a567d3b008632b8de17f133d7546
5
5
  SHA512:
6
- metadata.gz: ce1f26011bb2ed5658d22a92145a8f0732259e97e54bf15de28e4e6446e36b2b5015f063a67616c5e960f920db2a41dd4ea93dbe937d17f569f24f567718a579
7
- data.tar.gz: 182282dd0143a7c72c2ef222ef992e10148b2f547ae8985d155458a44ab2296d0f9b01fccdd4e1639d237d76f299b2d6c1adda4057d38a85226a2e0f4a98739b
6
+ metadata.gz: 8e210ad6e5512a36594cfef62dba1fd52562cda749db98a9ea81297e83ae92030398779286641a9787fdd6e4d31e6e546550fb7e59430d6ae5e3a90c389f1574
7
+ data.tar.gz: 4e7040c017aa1d7c1b4700cb79bccb041c36105a8829d7252cc01a7af660266ea76e86cf0f916fa1145fc9742ca6b9f0d5a9b14b6369c0d983750e011b9f35ce
@@ -1,23 +1,24 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cai-ecs-entrypoint (1.1.0)
4
+ cai-ecs-entrypoint (2.0.1)
5
5
  aws-sdk-ssm (~> 1)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- aws-eventstream (1.0.1)
11
- aws-partitions (1.140.0)
12
- aws-sdk-core (3.46.2)
13
- aws-eventstream (~> 1.0)
14
- aws-partitions (~> 1.0)
15
- aws-sigv4 (~> 1.0)
10
+ aws-eventstream (1.1.0)
11
+ aws-partitions (1.409.0)
12
+ aws-sdk-core (3.110.0)
13
+ aws-eventstream (~> 1, >= 1.0.2)
14
+ aws-partitions (~> 1, >= 1.239.0)
15
+ aws-sigv4 (~> 1.1)
16
16
  jmespath (~> 1.0)
17
- aws-sdk-ssm (1.36.0)
18
- aws-sdk-core (~> 3, >= 3.39.0)
19
- aws-sigv4 (~> 1.0)
20
- aws-sigv4 (1.0.3)
17
+ aws-sdk-ssm (1.100.0)
18
+ aws-sdk-core (~> 3, >= 3.109.0)
19
+ aws-sigv4 (~> 1.1)
20
+ aws-sigv4 (1.2.2)
21
+ aws-eventstream (~> 1, >= 1.0.2)
21
22
  jmespath (1.4.0)
22
23
 
23
24
  PLATFORMS
data/README.md CHANGED
@@ -1,30 +1,44 @@
1
1
  # Cai::Ecs::Entrypoint
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/cai/ecs/entrypoint`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ This gem provides an easy and convenient method for Docker-based applications to retrieve configuration as environment variables at application startup.
6
4
 
7
5
  ## Installation
8
6
 
9
- Add this line to your application's Gemfile:
7
+ Add the following line to your application's `Dockerfile` as early as possible, preferrably following the `FROM` statement:
8
+
9
+ ```dockerfile
10
+ FROM some/base
11
+
12
+ # If necessary, install Ruby runtime; omit if container already includes Ruby, such as a Rails app
13
+ RUN apt-get update && apt-get -y install ruby
10
14
 
11
- ```ruby
12
- gem 'cai-ecs-entrypoint'
15
+ # Install cai-ecs-entrypoint gem
16
+ RUN gem install cai-ecs-entrypoint -v 1.1.0
13
17
  ```
14
18
 
15
- And then execute:
19
+ Installing the Ruby runtime and gem early in the Docker file allows Docker container layer caching and will improve build times.
16
20
 
17
- $ bundle
21
+ ## Usage
18
22
 
19
- Or install it yourself as:
23
+ To use the gem, alter your container's `Dockerfile` to specify the `ENTRYPOINT`:
20
24
 
21
- $ gem install cai-ecs-entrypoint
25
+ ```dockerfile
26
+ ENTRYPOINT ["ssm-entrypoint"]
27
+ CMD ["your-executable", "arg1", "arg2", "...argN"]
28
+ ```
22
29
 
23
- ## Usage
30
+ The SSM Entrypoint requires two environment variables to be set when running the container:
31
+
32
+ * `AWS_REGION`: specifies the AWS region storing the SSM parameters used for this application
33
+ * `SSM_KEY_PATH`: path-notated prefix for all keys that the entrypoint should fetch, e.g. `/stage/myApp`
34
+
35
+ Both of these environment variables are provided _automatically_ for applications running on the Docker-based AWS Deployment Pipeline, such as used by CentralDispatch.
36
+
37
+ When using `docker-compose` locally, the entrypoint gem will _do nothing_, since proper AWS IAM credentials are required to fetch configuration. Use the `docker-compose.yml`, `docker-compose.override.yml`, or other mechanism, to provide environment variables locally.
24
38
 
25
- TODO: Write usage instructions here
39
+ In AWS, if the entrypoint script is unable to fetch configuration, the application will fail to start. This is _by design_ to prevent the application from starting in an unexpected or unpredictable state.
26
40
 
27
- ## Development
41
+ ## Gem Development
28
42
 
29
43
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
44
 
@@ -1,41 +1,26 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- env = {}
4
-
5
3
  if ENV.has_key?('SSM_KEY_PATH')
6
- require 'aws-sdk-ssm'
4
+ require 'docker/pipeline/ssm_parameters'
5
+ require 'timeout'
7
6
 
8
7
  puts 'Injecting application secrets...'
9
8
 
10
9
  begin
11
- client = Aws::SSM::Client.new
12
-
13
- next_token = nil
14
- loop do
15
- secrets = client.get_parameters_by_path(
16
- path: ENV.fetch('SSM_KEY_PATH'),
17
- with_decryption: true,
18
- next_token: next_token
19
- )
20
-
21
- secrets.parameters.map do |parameter|
22
- key = parameter.name.split('/').last
23
- value = parameter.value
24
- env[key] = value
25
- end
26
-
27
- next_token = secrets.next_token
28
- break unless next_token
29
-
30
- sleep 1 # don't overrun the API rate limit
31
- end
10
+ ssm_key_path = ENV.fetch('SSM_KEY_PATH')
11
+ exec Docker::Pipeline::SsmParameters.at(ssm_key_path), *ARGV
32
12
  rescue Aws::Errors::MissingRegionError
33
13
  puts 'Error: Missing AWS Region'
34
14
  exit 1
35
15
  rescue Aws::Errors::MissingCredentialsError
36
16
  puts 'Error: Missing AWS Credentials'
37
17
  exit 2
18
+ rescue Docker::Pipeline::ExcessiveThrottlingError
19
+ puts 'Error: Unable to fetch all SSM Parameters; exhausted retries due to API throttling!'
20
+ exit 3
21
+ rescue Timeout::Error
22
+ puts 'Error: Unable to fetch all SSM Parameters; exhausted maximum allowable time to complete!'
38
23
  end
24
+ else
25
+ exec *ARGV
39
26
  end
40
-
41
- exec env, *ARGV
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["jarrod.carlson@coxautoinc.com"]
11
11
 
12
12
  spec.summary = %q{Entrypoint script for ECS containers }
13
- spec.description = %q{Injects SSM paramters into Docker containers running on AWS ECS}
13
+ spec.description = %q{Injects SSM parameters into Docker containers running on AWS ECS}
14
14
  spec.homepage = "https://ghe.coxautoinc.com/Transportation/cai-ecs-entrypoint"
15
15
 
16
16
  # Specify which files should be added to the gem when it is released.
@@ -1,7 +1,7 @@
1
1
  module Cai
2
2
  module Ecs
3
3
  module Entrypoint
4
- VERSION = "1.1.0"
4
+ VERSION = "2.0.1"
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,74 @@
1
+ require 'aws-sdk-ssm'
2
+ require 'timeout'
3
+
4
+ module Docker
5
+ module Pipeline
6
+ class ExcessiveThrottlingError < StandardError; end
7
+
8
+ class SsmParameters
9
+ CLIENT = Aws::SSM::Client.new
10
+
11
+ def self.at(path)
12
+ new(path).to_h
13
+ end
14
+
15
+ def to_h
16
+ env
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :path
22
+ attr_reader :env
23
+
24
+ def initialize(path)
25
+ @path = path
26
+ @env = {}
27
+ @pages = 0
28
+
29
+ next_token = nil
30
+
31
+ Timeout::timeout(60) do
32
+ loop do
33
+ next_token = read_page next_page(next_token)
34
+ break unless next_token
35
+ end
36
+ end
37
+ end
38
+
39
+ def read_page(page)
40
+ page.parameters.each do |parameter|
41
+ key = parameter.name.split('/').last
42
+ value = parameter.value
43
+ env[key] = value
44
+ end
45
+
46
+ page.next_token
47
+ end
48
+
49
+ def next_page(next_token)
50
+ @pages += 1
51
+
52
+ with_exponential_backoff do
53
+ CLIENT.get_parameters_by_path(
54
+ path: path,
55
+ with_decryption: true,
56
+ next_token: next_token
57
+ )
58
+ end
59
+ end
60
+
61
+ def with_exponential_backoff(max_attempts = 10, backoff = 0.5)
62
+ max_attempts.times do |try|
63
+ begin
64
+ return yield
65
+ rescue Aws::SSM::Errors::ThrottlingException
66
+ raise ExcessiveThrottlingError unless try < (max_attempts - 1)
67
+ puts 'Backing off and retrying due to API throttling'
68
+ sleep (try ** backoff) + (rand * 1.5)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cai-ecs-entrypoint
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jarrod Carlson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-22 00:00:00.000000000 Z
11
+ date: 2020-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-ssm
@@ -24,7 +24,7 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1'
27
- description: Injects SSM paramters into Docker containers running on AWS ECS
27
+ description: Injects SSM parameters into Docker containers running on AWS ECS
28
28
  email:
29
29
  - jarrod.carlson@coxautoinc.com
30
30
  executables:
@@ -40,10 +40,11 @@ files:
40
40
  - bin/ssm-entrypoint
41
41
  - cai-ecs-entrypoint.gemspec
42
42
  - lib/cai/ecs/entrypoint/version.rb
43
+ - lib/docker/pipeline/ssm_parameters.rb
43
44
  homepage: https://ghe.coxautoinc.com/Transportation/cai-ecs-entrypoint
44
45
  licenses: []
45
46
  metadata: {}
46
- post_install_message:
47
+ post_install_message:
47
48
  rdoc_options: []
48
49
  require_paths:
49
50
  - lib
@@ -58,9 +59,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
59
  - !ruby/object:Gem::Version
59
60
  version: '0'
60
61
  requirements: []
61
- rubyforge_project:
62
+ rubyforge_project:
62
63
  rubygems_version: 2.7.6
63
- signing_key:
64
+ signing_key:
64
65
  specification_version: 4
65
66
  summary: Entrypoint script for ECS containers
66
67
  test_files: []