cai-ecs-entrypoint 1.1.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []