terraspace_plugin_aws 0.3.3 → 0.3.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +4 -0
- data/lib/templates/hcl/module/main.tf +5 -1
- data/lib/templates/ruby/module/main.rb +4 -0
- data/lib/terraspace_plugin_aws/clients/options.rb +4 -6
- data/lib/terraspace_plugin_aws/clients.rb +5 -0
- data/lib/terraspace_plugin_aws/interfaces/backend/bucket/secure.rb +1 -0
- data/lib/terraspace_plugin_aws/interfaces/backend/bucket/tagging.rb +44 -0
- data/lib/terraspace_plugin_aws/interfaces/backend/bucket.rb +8 -2
- data/lib/terraspace_plugin_aws/interfaces/backend/setup.rb +15 -0
- data/lib/terraspace_plugin_aws/interfaces/backend/table.rb +26 -0
- data/lib/terraspace_plugin_aws/interfaces/backend.rb +1 -0
- data/lib/terraspace_plugin_aws/interfaces/config.rb +7 -2
- data/lib/terraspace_plugin_aws/interfaces/helper/secret.rb +5 -0
- data/lib/terraspace_plugin_aws/interfaces/helper/secret_base.rb +14 -1
- data/lib/terraspace_plugin_aws/interfaces/helper/ssm.rb +8 -0
- data/lib/terraspace_plugin_aws/interfaces/helper.rb +2 -2
- data/lib/terraspace_plugin_aws/version.rb +1 -1
- data/terraspace_plugin_aws.gemspec +1 -1
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f6548d387f1353c70c8d7ce848f22f5e77f3cc0e9c2aaa19c9357c724b77ce9
|
4
|
+
data.tar.gz: 140d53ddb0ee7688a90b8acc04189d48079c88685d9d296420b8df3e5b9f05bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f920f7e43bb2fdd470ddbf1a12c906f0d76b4630070f466929d01941c82daead85cb7a5f955d9ca9dad129cbd144f91c81e9a6c4f7e84dbdd58585cf99c83e51
|
7
|
+
data.tar.gz: e61f88175f512a64687521f8cbc78b484702e2367d6c0eb65e40ef2a4a019a68ca54487b145787cfa525870437ff59aac61b459b735468759ec1d388a5ec02a9
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,20 @@
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/).
|
5
5
|
|
6
|
+
## [0.3.7] - 2022-02-15
|
7
|
+
- [#18](https://github.com/boltops-tools/terraspace_plugin_aws/pull/18) update starter s3 bucket example to work with terraform aws provider v4
|
8
|
+
|
9
|
+
## [0.3.6] - 2022-01-04
|
10
|
+
- [#17](https://github.com/boltops-tools/terraspace_plugin_aws/pull/17) aws_secret and aws_ssm: support expansion automatically
|
11
|
+
|
12
|
+
## [0.3.5] - 2021-12-30
|
13
|
+
- [#15](https://github.com/boltops-tools/terraspace_plugin_aws/pull/15) block public access support
|
14
|
+
- [#16](https://github.com/boltops-tools/terraspace_plugin_aws/pull/16) tagging support for s3 bucket and dynamodb table
|
15
|
+
|
16
|
+
## [0.3.4] - 2021-12-30
|
17
|
+
- [#13](https://github.com/boltops-tools/terraspace_plugin_aws/pull/13) check aws setup and provide friendly message
|
18
|
+
- [#14](https://github.com/boltops-tools/terraspace_plugin_aws/pull/14) fix aws_secret helper
|
19
|
+
|
6
20
|
## [0.3.3] - 2021-12-14
|
7
21
|
- [#10](https://github.com/boltops-tools/terraspace_plugin_aws/pull/10) implement expand_string? to not expand aws arn values
|
8
22
|
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Terraspace AWS Plugin
|
2
2
|
|
3
|
+
[![BoltOps Badge](https://img.boltops.com/boltops/badges/boltops-badge.png)](https://www.boltops.com)
|
4
|
+
|
3
5
|
AWS Cloud support for terraspace.
|
4
6
|
|
5
7
|
## Installation
|
@@ -12,6 +14,8 @@ gem 'terraspace_plugin_aws'
|
|
12
14
|
|
13
15
|
## Configure
|
14
16
|
|
17
|
+
Terraspace Docs: [AWS Terraspace Plugin](https://terraspace.cloud/docs/plugins/aws/)
|
18
|
+
|
15
19
|
Optionally configure the plugin. Here's an example `aws.rb` for your terraspace project.
|
16
20
|
|
17
21
|
config/plugins/aws.rb
|
@@ -2,8 +2,9 @@ module TerraspacePluginAws::Clients
|
|
2
2
|
module Options
|
3
3
|
private
|
4
4
|
def client_options
|
5
|
+
return {} unless @info # aws_secret helper wont have @info
|
5
6
|
if @info['role_arn']
|
6
|
-
|
7
|
+
client_assume_role_options
|
7
8
|
else
|
8
9
|
client_default_options
|
9
10
|
end
|
@@ -31,7 +32,7 @@ module TerraspacePluginAws::Clients
|
|
31
32
|
# :external_id (String)
|
32
33
|
# :client (STS::Client)
|
33
34
|
#
|
34
|
-
def
|
35
|
+
def client_assume_role_options
|
35
36
|
whitelist = %w[
|
36
37
|
assume_role_duration_seconds
|
37
38
|
assume_role_policy
|
@@ -59,10 +60,7 @@ module TerraspacePluginAws::Clients
|
|
59
60
|
end
|
60
61
|
assume_role_config.symbolize_keys! # ruby sdk expects symbols for keys
|
61
62
|
assume_role_config[:role_session_name] ||= [ENV['C9_USER'] || ENV['USER'], 'session'].compact.join('-') # session name is required for the ruby sdk
|
62
|
-
|
63
|
-
options = {}
|
64
|
-
options.merge!(assume_role_config)
|
65
|
-
role_credentials = Aws::AssumeRoleCredentials.new(options)
|
63
|
+
role_credentials = Aws::AssumeRoleCredentials.new(assume_role_config)
|
66
64
|
{credentials: role_credentials}
|
67
65
|
end
|
68
66
|
|
@@ -31,6 +31,7 @@ class TerraspacePluginAws::Interfaces::Backend::Bucket
|
|
31
31
|
S3Secure::Versioning::Enable.new(options).run if c.versioning
|
32
32
|
S3Secure::Lifecycle::Add.new(options).run if c.lifecycle
|
33
33
|
S3Secure::AccessLogs::Enable.new(options).run if c.access_logging
|
34
|
+
S3Secure::PublicAccess::Block.new(options).run if c.block_public_access
|
34
35
|
rescue Aws::S3::Errors::AccessDenied => e
|
35
36
|
@@retries += 1
|
36
37
|
retry unless @@retries > 1
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class TerraspacePluginAws::Interfaces::Backend::Bucket
|
2
|
+
class Tagging
|
3
|
+
include TerraspacePluginAws::Clients
|
4
|
+
include TerraspacePluginAws::Logging
|
5
|
+
|
6
|
+
def initialize(bucket)
|
7
|
+
@bucket = bucket
|
8
|
+
end
|
9
|
+
|
10
|
+
def tag
|
11
|
+
return if tagging.nil? || tagging[:tag_set].empty? # safeguard: dont overwrite current tags
|
12
|
+
s3.put_bucket_tagging(bucket: @bucket, tagging: tagging)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Merges existing tag_set structure so always appends tags, wont remove tags.
|
16
|
+
# This behavior is consistent with the dynamodb tagging.
|
17
|
+
#
|
18
|
+
# Example return:
|
19
|
+
#
|
20
|
+
# {
|
21
|
+
# tag_set: [
|
22
|
+
# { key: "Key1", value: "Value1" },
|
23
|
+
# { key: "Key2", value: "Value2" },
|
24
|
+
# ],
|
25
|
+
# }
|
26
|
+
#
|
27
|
+
def tagging
|
28
|
+
c = TerraspacePluginAws::Interfaces::Config.instance.config
|
29
|
+
tags = !c.s3.tags.empty? ? c.s3.tags : c.tags
|
30
|
+
tag_set = tags.map do |k,v|
|
31
|
+
{key: k.to_s, value: v}
|
32
|
+
end
|
33
|
+
return if tag_set == existing_tagging[:tag_set] # return nil so we can avoid the put_bucket_tagging call
|
34
|
+
tag_set += existing_tagging[:tag_set]
|
35
|
+
{ tag_set: tag_set }
|
36
|
+
end
|
37
|
+
|
38
|
+
def existing_tagging
|
39
|
+
s3.get_bucket_tagging(bucket: @bucket).to_h
|
40
|
+
rescue Aws::S3::Errors::NoSuchTagSet
|
41
|
+
{tag_set: []} # normalize return structure
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -10,12 +10,14 @@ class TerraspacePluginAws::Interfaces::Backend
|
|
10
10
|
end
|
11
11
|
if exist?(bucket)
|
12
12
|
logger.debug "Bucket already exist: #{bucket}"
|
13
|
-
c = TerraspacePluginAws::Interfaces::Config.instance.config
|
14
|
-
secure(bucket) if c.secure_existing
|
13
|
+
c = TerraspacePluginAws::Interfaces::Config.instance.config
|
14
|
+
secure(bucket) if c.s3.secure_existing
|
15
|
+
tag(bucket) if c.tag_existing
|
15
16
|
else
|
16
17
|
logger.info "Creating bucket: #{bucket}"
|
17
18
|
s3.create_bucket(bucket: bucket)
|
18
19
|
secure(bucket)
|
20
|
+
tag(bucket)
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
@@ -30,5 +32,9 @@ class TerraspacePluginAws::Interfaces::Backend
|
|
30
32
|
logger.error "Bucket might be owned by someone else or is on another one of your AWS accounts."
|
31
33
|
exit 1
|
32
34
|
end
|
35
|
+
|
36
|
+
def tag(bucket)
|
37
|
+
Tagging.new(@info["bucket"]).tag
|
38
|
+
end
|
33
39
|
end
|
34
40
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class TerraspacePluginAws::Interfaces::Backend
|
2
|
+
class Setup < Base
|
3
|
+
def check!
|
4
|
+
sts.get_caller_identity
|
5
|
+
rescue Aws::Errors::MissingCredentialsError => e
|
6
|
+
logger.info "ERROR: #{e.class}: #{e.message}".color(:red)
|
7
|
+
logger.info <<~EOL
|
8
|
+
It doesnt look like AWS credentials and access has been setup.
|
9
|
+
Please double check the AWS credentials setup.
|
10
|
+
IE: ~/.aws/config and the AWS_PROFILE env variable.
|
11
|
+
EOL
|
12
|
+
exit 1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -6,6 +6,8 @@ class TerraspacePluginAws::Interfaces::Backend
|
|
6
6
|
|
7
7
|
if exist?(table)
|
8
8
|
logger.debug "Table already exist: #{table}"
|
9
|
+
c = TerraspacePluginAws::Interfaces::Config.instance.config
|
10
|
+
tag_existing(table) if c.tag_existing
|
9
11
|
else
|
10
12
|
logger.info "Creating dynamodb table: #{table}"
|
11
13
|
create_table(table)
|
@@ -36,6 +38,7 @@ class TerraspacePluginAws::Interfaces::Backend
|
|
36
38
|
table_name: name,
|
37
39
|
}
|
38
40
|
secure(definition)
|
41
|
+
tag(definition)
|
39
42
|
definition
|
40
43
|
end
|
41
44
|
|
@@ -64,6 +67,29 @@ class TerraspacePluginAws::Interfaces::Backend
|
|
64
67
|
definition
|
65
68
|
end
|
66
69
|
|
70
|
+
def tag(definition)
|
71
|
+
definition[:tags] = tags unless tags.empty?
|
72
|
+
end
|
73
|
+
|
74
|
+
def tag_existing(table_name)
|
75
|
+
return if tags.empty?
|
76
|
+
resp = dynamodb.describe_table(table_name: table_name)
|
77
|
+
# Always appends tags, wont remove tags.
|
78
|
+
dynamodb.tag_resource(
|
79
|
+
resource_arn: resp.table.table_arn,
|
80
|
+
tags: tags
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
def tags
|
85
|
+
c = TerraspacePluginAws::Interfaces::Config.instance.config
|
86
|
+
tags = !c.dynamodb.tags.empty? ? c.dynamodb.tags : c.tags
|
87
|
+
# Note there is no map! method for Hash
|
88
|
+
tags = tags.map do |k,v|
|
89
|
+
{key: k.to_s, value: v}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
67
93
|
def exist?(name)
|
68
94
|
dynamodb.describe_table(table_name: name)
|
69
95
|
true # table exist
|
@@ -14,19 +14,24 @@ module TerraspacePluginAws::Interfaces
|
|
14
14
|
c = ActiveSupport::OrderedOptions.new
|
15
15
|
|
16
16
|
c.auto_create = true
|
17
|
+
c.tags = {} # can set tags for both s3 bucket and dynamodb table with this config
|
18
|
+
c.tag_existing = true
|
17
19
|
|
18
20
|
c.s3 = ActiveSupport::OrderedOptions.new
|
21
|
+
c.s3.access_logging = false
|
22
|
+
c.s3.block_public_access = true
|
19
23
|
c.s3.encryption = true
|
20
24
|
c.s3.enforce_ssl = true
|
21
|
-
c.s3.versioning = true
|
22
25
|
c.s3.lifecycle = true
|
23
|
-
c.s3.
|
26
|
+
c.s3.versioning = true
|
24
27
|
c.s3.secure_existing = false # run the security controls on existing buckets. by default, only run on newly created bucket the first time
|
28
|
+
c.s3.tags = {} # cannot assign to c.tags here because it's a copy
|
25
29
|
|
26
30
|
c.dynamodb = ActiveSupport::OrderedOptions.new
|
27
31
|
c.dynamodb.encryption = true
|
28
32
|
c.dynamodb.kms_master_key_id = nil
|
29
33
|
c.dynamodb.sse_type = "KMS"
|
34
|
+
c.dynamodb.tags = {} # cannot assign to c.tags here because it's a copy
|
30
35
|
|
31
36
|
c
|
32
37
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module TerraspacePluginAws::Interfaces::Helper
|
2
2
|
class Secret < SecretBase
|
3
3
|
def fetch(secret_id)
|
4
|
+
secret_id = expansion(secret_id) if expand?
|
4
5
|
value = fetch_value(secret_id)
|
5
6
|
value = Base64.strict_encode64(value).strip if @base64
|
6
7
|
value
|
@@ -13,6 +14,10 @@ module TerraspacePluginAws::Interfaces::Helper
|
|
13
14
|
logger.info "WARN: secret_id #{secret_id} not found".color(:yellow)
|
14
15
|
logger.info e.message
|
15
16
|
"NOT FOUND #{secret_id}" # simple string so Kubernetes YAML is valid
|
17
|
+
rescue Aws::SecretsManager::Errors::ValidationException => e
|
18
|
+
logger.info "WARN: secret_id #{secret_id} not found".color(:yellow)
|
19
|
+
logger.info e.message
|
20
|
+
"INVALID NAME #{secret_id}" # simple string so tfvars valid
|
16
21
|
end
|
17
22
|
end
|
18
23
|
end
|
@@ -4,10 +4,23 @@ module TerraspacePluginAws::Interfaces::Helper
|
|
4
4
|
class SecretBase
|
5
5
|
include TerraspacePluginAws::Clients
|
6
6
|
include TerraspacePluginAws::Logging
|
7
|
+
extend Memoist
|
7
8
|
|
8
|
-
def initialize(options={})
|
9
|
+
def initialize(mod, options={})
|
10
|
+
@mod = mod
|
9
11
|
@options = options
|
10
12
|
@base64 = options[:base64]
|
11
13
|
end
|
14
|
+
|
15
|
+
private
|
16
|
+
delegate :expansion, to: :expander
|
17
|
+
def expander
|
18
|
+
TerraspacePluginAws::Interfaces::Expander.new(@mod)
|
19
|
+
end
|
20
|
+
memoize :expander
|
21
|
+
|
22
|
+
def expand?
|
23
|
+
!(@options[:expansion] == false || @options[:expand] == false)
|
24
|
+
end
|
12
25
|
end
|
13
26
|
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module TerraspacePluginAws::Interfaces::Helper
|
2
2
|
class SSM < SecretBase
|
3
|
+
include Terraspace::Compiler::Dsl::Syntax::Mod::Backend
|
4
|
+
extend Memoist
|
5
|
+
|
3
6
|
def fetch(name)
|
7
|
+
name = expansion(name) if expand?
|
4
8
|
value = fetch_value(name)
|
5
9
|
value = Base64.strict_encode64(value).strip if @base64
|
6
10
|
value
|
@@ -13,6 +17,10 @@ module TerraspacePluginAws::Interfaces::Helper
|
|
13
17
|
logger.info "WARN: name #{name} not found".color(:yellow)
|
14
18
|
logger.info e.message
|
15
19
|
"NOT FOUND #{name}" # simple string so tfvars valid
|
20
|
+
rescue Aws::SSM::Errors::ValidationException => e
|
21
|
+
logger.info "WARN: name #{name} not found".color(:yellow)
|
22
|
+
logger.info e.message
|
23
|
+
"INVALID NAME #{name}" # simple string so tfvars valid
|
16
24
|
end
|
17
25
|
end
|
18
26
|
end
|
@@ -3,12 +3,12 @@ module TerraspacePluginAws::Interfaces
|
|
3
3
|
include Terraspace::Plugin::Helper::Interface
|
4
4
|
|
5
5
|
def aws_secret(name, options={})
|
6
|
-
Secret.new(options).fetch(name)
|
6
|
+
Secret.new(@mod, options).fetch(name)
|
7
7
|
end
|
8
8
|
cache_helper :aws_secret
|
9
9
|
|
10
10
|
def aws_ssm(name, options={})
|
11
|
-
SSM.new(options).fetch(name)
|
11
|
+
SSM.new(@mod, options).fetch(name)
|
12
12
|
end
|
13
13
|
cache_helper :aws_ssm
|
14
14
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: terraspace_plugin_aws
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tung Nguyen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-dynamodb
|
@@ -98,16 +98,16 @@ dependencies:
|
|
98
98
|
name: s3-secure
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
103
|
+
version: 0.6.1
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
110
|
+
version: 0.6.1
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: zeitwerk
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -172,6 +172,8 @@ files:
|
|
172
172
|
- lib/terraspace_plugin_aws/interfaces/backend/base.rb
|
173
173
|
- lib/terraspace_plugin_aws/interfaces/backend/bucket.rb
|
174
174
|
- lib/terraspace_plugin_aws/interfaces/backend/bucket/secure.rb
|
175
|
+
- lib/terraspace_plugin_aws/interfaces/backend/bucket/tagging.rb
|
176
|
+
- lib/terraspace_plugin_aws/interfaces/backend/setup.rb
|
175
177
|
- lib/terraspace_plugin_aws/interfaces/backend/table.rb
|
176
178
|
- lib/terraspace_plugin_aws/interfaces/config.rb
|
177
179
|
- lib/terraspace_plugin_aws/interfaces/decorator.rb
|