scout-camp 0.1.8 → 0.1.11
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/.vimproject +26 -0
- data/VERSION +1 -1
- data/lib/scout/aws/s3.rb +123 -15
- data/lib/scout/offsite/resource.rb +1 -1
- data/lib/scout/terraform_dsl.rb +7 -0
- data/lib/scout-camp.rb +1 -0
- data/scout-camp.gemspec +16 -4
- data/scout_commands/sync +1 -0
- data/scout_commands/terraform/lambda_task +9 -5
- data/share/aws/lambda_function.rb +24 -7
- data/share/terraform/aws/container_lambda/data.tf +15 -0
- data/share/terraform/aws/container_lambda/locals.tf +8 -0
- data/share/terraform/aws/container_lambda/main.tf +47 -0
- data/share/terraform/aws/container_lambda/variables.tf +44 -0
- data/share/terraform/aws/efs_host/main.tf +2 -1
- data/share/terraform/aws/efs_host/variables.tf +9 -1
- data/share/terraform/aws/fargate/main.tf +4 -1
- data/share/terraform/aws/fargate/variables.tf +16 -5
- data/share/terraform/aws/iam_instance_profile/main.tf +5 -0
- data/share/terraform/aws/iam_instance_profile/output.tf +15 -0
- data/share/terraform/aws/iam_instance_profile/variables.tf +9 -0
- data/share/terraform/aws/lambda/main.tf +1 -1
- data/share/terraform/aws/lambda/variables.tf +3 -4
- data/share/terraform/aws/policy/main.tf +8 -0
- data/share/terraform/aws/policy/output.tf +15 -0
- data/share/terraform/aws/policy/variables.tf +12 -0
- data/share/terraform/aws/role/main.tf +1 -1
- data/share/terraform/aws/role/output.tf +1 -1
- data/share/terraform/aws/role/variables.tf +4 -1
- data/share/terraform/aws/role_policy/main.tf +9 -0
- data/share/terraform/aws/role_policy/variables.tf +16 -0
- data/test/scout/aws/test_s3.rb +14 -1
- metadata +15 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4310a29a500f7fe04fb974b8a5cb3ae5aae506a9a3663663ec6bd86270c17fd2
|
4
|
+
data.tar.gz: a6e9b6a396a76f9ddde67a502658b9cb37cddeb12355c1bbe244c5f1ff7c3f36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86dbee75e288daf9d1be188a9d13e79b9656314ef3345e24d226fd79fa987c7723c4bd1d2df488a5a2e56e04cdcb97bf69e4a2ef0f2a88bde00713978ff3b4be
|
7
|
+
data.tar.gz: 7d7bd20736cad39b68d9dc0406490a5ea2a5095bec45dfe550fd2e5131ecbbdf4ecfbd21ac523cfcddadd163c4988465ad6358038d38a9c3d5151a48c50cb6cb
|
data/.vimproject
CHANGED
@@ -87,15 +87,41 @@ scout-camp=/$PWD filter="*" {
|
|
87
87
|
variables.tf
|
88
88
|
}
|
89
89
|
|
90
|
+
container_lambda=container_lambda{
|
91
|
+
main.tf
|
92
|
+
data.tf
|
93
|
+
locals.tf
|
94
|
+
variables.tf
|
95
|
+
}
|
96
|
+
|
90
97
|
role=role{
|
91
98
|
main.tf
|
92
99
|
variables.tf
|
93
100
|
output.tf
|
94
101
|
}
|
102
|
+
|
103
|
+
policy=policy{
|
104
|
+
main.tf
|
105
|
+
variables.tf
|
106
|
+
output.tf
|
107
|
+
}
|
108
|
+
|
109
|
+
role_policy=role_policy{
|
110
|
+
main.tf
|
111
|
+
variables.tf
|
112
|
+
}
|
113
|
+
|
95
114
|
policy_attachment=policy_attachment {
|
96
115
|
main.tf
|
97
116
|
variables.tf
|
98
117
|
}
|
118
|
+
|
119
|
+
iam_instance_profile=iam_instance_profile{
|
120
|
+
main.tf
|
121
|
+
variables.tf
|
122
|
+
output.tf
|
123
|
+
}
|
124
|
+
|
99
125
|
cluster=cluster {
|
100
126
|
main.tf
|
101
127
|
output.tf
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.11
|
data/lib/scout/aws/s3.rb
CHANGED
@@ -21,14 +21,18 @@ module Open
|
|
21
21
|
uri.start_with? 's3://'
|
22
22
|
end
|
23
23
|
|
24
|
-
def self.
|
24
|
+
def self.claim_uri(uri)
|
25
25
|
if Path === uri and not uri.located?
|
26
|
-
is_s3?
|
26
|
+
is_s3?(uri.find)
|
27
27
|
else
|
28
28
|
is_s3? uri
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
def self.claim(uri, uri2=nil, ...)
|
33
|
+
claim_uri(uri) || (String === uri2 && claim_uri(uri2))
|
34
|
+
end
|
35
|
+
|
32
36
|
def self.parse_s3_uri(uri)
|
33
37
|
uri = uri.find if Path === uri and not uri.located?
|
34
38
|
uri = uri.sub(%r{^s3://}, '')
|
@@ -59,7 +63,14 @@ module Open
|
|
59
63
|
s3.put_object(bucket: bucket, key: key, body: content)
|
60
64
|
end
|
61
65
|
|
62
|
-
def self.
|
66
|
+
def self.touch(uri)
|
67
|
+
if self.exists?(uri)
|
68
|
+
else
|
69
|
+
self.cp(uri, uri)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.glob(uri, pattern="*")
|
63
74
|
bucket, prefix = parse_s3_uri(uri)
|
64
75
|
s3 = Aws::S3::Client.new
|
65
76
|
matches = []
|
@@ -82,8 +93,19 @@ module Open
|
|
82
93
|
remaining = remaining.sub(%r{^/}, '')
|
83
94
|
end
|
84
95
|
|
96
|
+
Log.debug "Glob: #{remaining}"
|
97
|
+
|
85
98
|
if File.fnmatch?(pattern, remaining, File::FNM_PATHNAME)
|
86
99
|
matches << "s3://#{bucket}/#{key}"
|
100
|
+
else
|
101
|
+
dir = File.dirname(remaining)
|
102
|
+
while dir
|
103
|
+
if File.fnmatch?(pattern, dir, File::FNM_PATHNAME)
|
104
|
+
matches << "s3://#{bucket}/#{File.join(prefix,dir)}"
|
105
|
+
end
|
106
|
+
break if dir == File.dirname(dir)
|
107
|
+
dir = File.dirname(dir)
|
108
|
+
end
|
87
109
|
end
|
88
110
|
end
|
89
111
|
|
@@ -136,18 +158,22 @@ module Open
|
|
136
158
|
end
|
137
159
|
|
138
160
|
def self.cp(source, target)
|
139
|
-
|
140
|
-
|
161
|
+
if is_s3?(target)
|
162
|
+
source_bucket, source_key = parse_s3_uri(source)
|
163
|
+
target_bucket, target_key = parse_s3_uri(target)
|
141
164
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
165
|
+
s3 = Aws::S3::Client.new
|
166
|
+
s3.copy_object({
|
167
|
+
copy_source: "#{source_bucket}/#{source_key}",
|
168
|
+
bucket: target_bucket,
|
169
|
+
key: target_key
|
170
|
+
})
|
171
|
+
else
|
172
|
+
Open.sensible_write(target, get_stream(source))
|
173
|
+
end
|
148
174
|
end
|
149
175
|
|
150
|
-
def self.
|
176
|
+
def self.file_exists?(uri)
|
151
177
|
bucket, key = parse_s3_uri(uri)
|
152
178
|
return false if key.empty? # Can't check existence of bucket this way
|
153
179
|
|
@@ -157,6 +183,29 @@ module Open
|
|
157
183
|
rescue Aws::S3::Errors::NotFound, Aws::S3::Errors::NoSuchBucket
|
158
184
|
false
|
159
185
|
end
|
186
|
+
|
187
|
+
def self.directory?(uri)
|
188
|
+
bucket, key = parse_s3_uri(uri)
|
189
|
+
return false if key.empty? # Can't check existence of bucket this way
|
190
|
+
|
191
|
+
key += '/' unless key.end_with?('/')
|
192
|
+
s3 = Aws::S3::Client.new
|
193
|
+
response = s3.list_objects_v2({
|
194
|
+
bucket: bucket,
|
195
|
+
prefix: key,
|
196
|
+
max_keys: 1
|
197
|
+
})
|
198
|
+
|
199
|
+
!response.contents.empty?
|
200
|
+
end
|
201
|
+
|
202
|
+
def self.exists?(uri)
|
203
|
+
begin
|
204
|
+
file_exists?(uri) || directory?(uri)
|
205
|
+
rescue
|
206
|
+
false
|
207
|
+
end
|
208
|
+
end
|
160
209
|
|
161
210
|
self.singleton_class.alias_method :exist?, :exists?
|
162
211
|
|
@@ -179,6 +228,68 @@ module Open
|
|
179
228
|
def self.ln_s(source, target, options = {})
|
180
229
|
cp(source, target)
|
181
230
|
end
|
231
|
+
|
232
|
+
def self.sync(source, target, options = {})
|
233
|
+
excludes, files, hard_link, test, print, delete, other = IndiferentHash.process_options options,
|
234
|
+
:excludes, :files, :hard_link, :test, :print, :delete, :other
|
235
|
+
|
236
|
+
excludes ||= %w(.save .crap .source tmp filecache open-remote)
|
237
|
+
excludes = excludes.split(/,\s*/) if excludes.is_a?(String) and not excludes.include?("--exclude")
|
238
|
+
|
239
|
+
if File.directory?(source) || source.end_with?("/")
|
240
|
+
source += "/" unless source.end_with? '/'
|
241
|
+
target += "/" unless target.end_with? '/'
|
242
|
+
end
|
243
|
+
|
244
|
+
if source == target
|
245
|
+
Log.warn "Asking to sync with itself"
|
246
|
+
return
|
247
|
+
end
|
248
|
+
|
249
|
+
Log.low "Migrating #{source} #{files.length} files to #{target} - #{Misc.fingerprint(files)}}" if files
|
250
|
+
|
251
|
+
sync_args = %w()
|
252
|
+
sync_args << excludes.collect{|s| "--exclude '#{s}'" } if excludes and excludes.any?
|
253
|
+
sync_args << "-nv" if test
|
254
|
+
|
255
|
+
if files
|
256
|
+
tmp_files = TmpFile.tmp_file 's3_sync_files-'
|
257
|
+
Open.write(tmp_files, files * "\n")
|
258
|
+
sync_args << "--files-from='#{tmp_files}'"
|
259
|
+
end
|
260
|
+
|
261
|
+
if Open.directory?(source)
|
262
|
+
cmd = "aws s3 sync #{sync_args * " "} #{source} #{target}"
|
263
|
+
else
|
264
|
+
cmd = "aws s3 cp #{source} #{target}"
|
265
|
+
end
|
266
|
+
case other
|
267
|
+
when String
|
268
|
+
cmd << " " << other
|
269
|
+
when Array
|
270
|
+
cmd << " " << other * " "
|
271
|
+
end
|
272
|
+
cmd << " && rm -Rf #{source}" if delete && ! files
|
273
|
+
|
274
|
+
if print
|
275
|
+
cmd
|
276
|
+
else
|
277
|
+
CMD.cmd_log(cmd, :log => Log::HIGH)
|
278
|
+
|
279
|
+
if delete && files
|
280
|
+
remove_files = files.collect{|f| File.join(source, f) }
|
281
|
+
dirs = remove_files.select{|f| File.directory? f }
|
282
|
+
remove_files.each do |file|
|
283
|
+
next if dirs.include? file
|
284
|
+
Open.rm file
|
285
|
+
end
|
286
|
+
|
287
|
+
dirs.each do |dir|
|
288
|
+
FileUtils.rmdir dir if Dir.glob(dir).empty?
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
182
293
|
end
|
183
294
|
end
|
184
295
|
|
@@ -202,6 +313,3 @@ end
|
|
202
313
|
|
203
314
|
Hook.apply(Open::S3, Open)
|
204
315
|
Hook.apply(Path::S3, Path)
|
205
|
-
|
206
|
-
|
207
|
-
#$ ask -t code --file /home/miki/git/scout-camp/lib/scout/aws/s3.rb extend this file [[...]] to include a function called self.exists? that determines if a uri exists {{{
|
@@ -11,7 +11,7 @@ module Resource
|
|
11
11
|
resource = path.pkgdir if resource.nil? and path.is_a?(Path) and path.pkgdir.is_a?(Resource)
|
12
12
|
resource = Resource.default_resource if resource.nil?
|
13
13
|
|
14
|
-
if
|
14
|
+
if Path.located?(path)
|
15
15
|
real_paths = [path]
|
16
16
|
else
|
17
17
|
path = Path.setup(path, pkgdir: resource) unless path.is_a?(Path)
|
data/lib/scout/terraform_dsl.rb
CHANGED
@@ -86,6 +86,11 @@ class TerraformDSL
|
|
86
86
|
def to_json(*_args)
|
87
87
|
self
|
88
88
|
end
|
89
|
+
|
90
|
+
def method_missing(elem)
|
91
|
+
new = self + '.' + elem.to_s
|
92
|
+
new.extend DirectReference
|
93
|
+
end
|
89
94
|
end
|
90
95
|
|
91
96
|
MODULES_DIR = Scout.share.terraform
|
@@ -134,6 +139,8 @@ class TerraformDSL
|
|
134
139
|
|
135
140
|
if value.is_a?(String) && (m = value.match(/^module\.(.*)\.(.*)/))
|
136
141
|
value = Module::Output.new m[1], m[2]
|
142
|
+
elsif value.is_a?(Symbol)
|
143
|
+
value = variables[value]
|
137
144
|
end
|
138
145
|
|
139
146
|
acc << " #{name} = #{value.to_json}"
|
data/lib/scout-camp.rb
CHANGED
data/scout-camp.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: scout-camp 0.1.
|
5
|
+
# stub: scout-camp 0.1.11 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "scout-camp".freeze
|
9
|
-
s.version = "0.1.
|
9
|
+
s.version = "0.1.11".freeze
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Miguel Vazquez".freeze]
|
14
|
-
s.date = "
|
14
|
+
s.date = "2025-04-16"
|
15
15
|
s.description = "Functionalities to deploy and use scouts in remote servers like AWS".freeze
|
16
16
|
s.email = "mikisvaz@gmail.com".freeze
|
17
17
|
s.executables = ["scout-camp".freeze]
|
@@ -58,6 +58,10 @@ Gem::Specification.new do |s|
|
|
58
58
|
"share/terraform/aws/cluster/main.tf",
|
59
59
|
"share/terraform/aws/cluster/output.tf",
|
60
60
|
"share/terraform/aws/cluster/variables.tf",
|
61
|
+
"share/terraform/aws/container_lambda/data.tf",
|
62
|
+
"share/terraform/aws/container_lambda/locals.tf",
|
63
|
+
"share/terraform/aws/container_lambda/main.tf",
|
64
|
+
"share/terraform/aws/container_lambda/variables.tf",
|
61
65
|
"share/terraform/aws/efs/data.tf",
|
62
66
|
"share/terraform/aws/efs/locals.tf",
|
63
67
|
"share/terraform/aws/efs/main.tf",
|
@@ -75,12 +79,18 @@ Gem::Specification.new do |s|
|
|
75
79
|
"share/terraform/aws/host/main.tf",
|
76
80
|
"share/terraform/aws/host/output.tf",
|
77
81
|
"share/terraform/aws/host/variables.tf",
|
82
|
+
"share/terraform/aws/iam_instance_profile/main.tf",
|
83
|
+
"share/terraform/aws/iam_instance_profile/output.tf",
|
84
|
+
"share/terraform/aws/iam_instance_profile/variables.tf",
|
78
85
|
"share/terraform/aws/lambda/main.tf",
|
79
86
|
"share/terraform/aws/lambda/variables.tf",
|
80
87
|
"share/terraform/aws/network/data.tf",
|
81
88
|
"share/terraform/aws/network/main.tf",
|
82
89
|
"share/terraform/aws/network/output.tf",
|
83
90
|
"share/terraform/aws/network/variables.tf",
|
91
|
+
"share/terraform/aws/policy/main.tf",
|
92
|
+
"share/terraform/aws/policy/output.tf",
|
93
|
+
"share/terraform/aws/policy/variables.tf",
|
84
94
|
"share/terraform/aws/policy_attachment/main.tf",
|
85
95
|
"share/terraform/aws/policy_attachment/variables.tf",
|
86
96
|
"share/terraform/aws/provider/data.tf",
|
@@ -88,6 +98,8 @@ Gem::Specification.new do |s|
|
|
88
98
|
"share/terraform/aws/role/main.tf",
|
89
99
|
"share/terraform/aws/role/output.tf",
|
90
100
|
"share/terraform/aws/role/variables.tf",
|
101
|
+
"share/terraform/aws/role_policy/main.tf",
|
102
|
+
"share/terraform/aws/role_policy/variables.tf",
|
91
103
|
"share/terraform/ssh/cmd/main.tf",
|
92
104
|
"share/terraform/ssh/cmd/variables.tf",
|
93
105
|
"test/scout/aws/test_s3.rb",
|
@@ -100,7 +112,7 @@ Gem::Specification.new do |s|
|
|
100
112
|
]
|
101
113
|
s.homepage = "http://github.com/mikisvaz/scout-camp".freeze
|
102
114
|
s.licenses = ["MIT".freeze]
|
103
|
-
s.rubygems_version = "3.6.
|
115
|
+
s.rubygems_version = "3.6.6".freeze
|
104
116
|
s.summary = "Deploy you scouts".freeze
|
105
117
|
|
106
118
|
s.specification_version = 4
|
data/scout_commands/sync
CHANGED
@@ -12,6 +12,7 @@ $ #{$0} [<options>] <workflow> <task> [<other|->]*
|
|
12
12
|
|
13
13
|
-h--help Print this help
|
14
14
|
--prefix* Prefix, defaults to Scout
|
15
|
+
--queue Queue job
|
15
16
|
--clean Clean job
|
16
17
|
--recursive_clean Clean job recursively
|
17
18
|
EOF
|
@@ -28,14 +29,14 @@ end
|
|
28
29
|
|
29
30
|
raise ParamterException, "No workflow specified" if workflow.nil?
|
30
31
|
|
31
|
-
prefix, clean, recursive_clean = IndiferentHash.process_options options, :prefix, :clean, :recursive_clean,
|
32
|
+
prefix, clean, recursive_clean, queue = IndiferentHash.process_options options, :prefix, :clean, :recursive_clean, :queue,
|
32
33
|
prefix: "Scout"
|
33
34
|
|
34
35
|
require 'aws-sdk-lambda'
|
35
36
|
|
36
37
|
payload = {}
|
37
|
-
payload[
|
38
|
-
payload[
|
38
|
+
payload[:workflow] = workflow
|
39
|
+
payload[:task_name] = task_name
|
39
40
|
|
40
41
|
if clean
|
41
42
|
payload["clean"] = true
|
@@ -43,10 +44,13 @@ elsif recursive_clean
|
|
43
44
|
payload["clean"] = 'recursive'
|
44
45
|
end
|
45
46
|
|
47
|
+
payload["queue"] = true if queue
|
48
|
+
|
46
49
|
lambda_handler = "#{prefix}Job"
|
47
50
|
|
48
51
|
def aws_lambda(name, payload)
|
49
52
|
client = Aws::Lambda::Client.new
|
53
|
+
Log.debug "Sending Lambda #{name} #{Log.fingerprint payload}"
|
50
54
|
resp = client.invoke({
|
51
55
|
function_name: name,
|
52
56
|
payload: payload.to_json,
|
@@ -64,7 +68,7 @@ def SOPT_str(task_info)
|
|
64
68
|
boolean = type.to_sym == :boolean
|
65
69
|
|
66
70
|
sopt_options << "-#{shortcut}--#{name}#{boolean ? "" : "*"}"
|
67
|
-
end
|
71
|
+
end if task_info[:inputs]
|
68
72
|
|
69
73
|
sopt_options * ":"
|
70
74
|
end
|
@@ -81,7 +85,7 @@ def get_SOPT(task_info)
|
|
81
85
|
if job_options.include?(name) && (! Open.exist?(job_options[name]) || type.to_s.include?('file') || type.to_s.include?('path'))
|
82
86
|
job_options[name] = job_options[name].split(",")
|
83
87
|
end
|
84
|
-
end
|
88
|
+
end if task_info[:inputs]
|
85
89
|
job_options
|
86
90
|
end
|
87
91
|
|
@@ -7,10 +7,10 @@ def lambda_handler(event:, context:)
|
|
7
7
|
require 'scout/workflow'
|
8
8
|
require 'scout/aws/s3'
|
9
9
|
|
10
|
-
workflow, task_name, jobname, inputs, clean = IndiferentHash.process_options event,
|
11
|
-
|
10
|
+
workflow, task_name, jobname, inputs, clean, queue = IndiferentHash.process_options event,
|
11
|
+
:workflow, :task_name, :jobname, :inputs, :clean, :queue
|
12
12
|
|
13
|
-
raise
|
13
|
+
raise ParameterException, "No workflow specified" if workflow.nil?
|
14
14
|
|
15
15
|
workflow = Workflow.require_workflow workflow
|
16
16
|
|
@@ -18,7 +18,7 @@ def lambda_handler(event:, context:)
|
|
18
18
|
when nil
|
19
19
|
return {tasks: workflow.tasks.keys, documentation: workflow.documentation}
|
20
20
|
when "info"
|
21
|
-
raise
|
21
|
+
raise ParameterException, "No task_name specified" if task_name.nil?
|
22
22
|
return workflow.task_info(inputs["task_name"])
|
23
23
|
else
|
24
24
|
job = workflow.job(task_name, jobname, inputs)
|
@@ -30,8 +30,25 @@ def lambda_handler(event:, context:)
|
|
30
30
|
job.recursive_clean
|
31
31
|
end
|
32
32
|
|
33
|
-
job.
|
34
|
-
|
35
|
-
job.
|
33
|
+
if job.done?
|
34
|
+
job.load
|
35
|
+
elsif job.error?
|
36
|
+
raise job.exception
|
37
|
+
elsif job.started?
|
38
|
+
{
|
39
|
+
statusCode: 202,
|
40
|
+
body: job.path
|
41
|
+
}
|
42
|
+
elsif queue
|
43
|
+
save_inputs = Scout.var.queue[workflow.to_s][task_name][job.name].find :bucket
|
44
|
+
job.save_inputs(save_inputs)
|
45
|
+
{
|
46
|
+
statusCode: 202,
|
47
|
+
body: job.path
|
48
|
+
}
|
49
|
+
else
|
50
|
+
job.produce
|
51
|
+
job.load
|
52
|
+
end
|
36
53
|
end
|
37
54
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
resource "aws_efs_access_point" "lambda_ap" {
|
2
|
+
file_system_id = local.efs_id
|
3
|
+
|
4
|
+
posix_user {
|
5
|
+
uid = 1000
|
6
|
+
gid = 1000
|
7
|
+
}
|
8
|
+
|
9
|
+
root_directory {
|
10
|
+
path = var.mount_point
|
11
|
+
creation_info {
|
12
|
+
owner_uid = 1000
|
13
|
+
owner_gid = 1000
|
14
|
+
permissions = "755"
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
resource "aws_lambda_function" "this" {
|
20
|
+
function_name = var.function_name
|
21
|
+
package_type = "Image"
|
22
|
+
|
23
|
+
image_uri = var.image
|
24
|
+
|
25
|
+
role = var.role_arn
|
26
|
+
|
27
|
+
timeout = var.timeout
|
28
|
+
memory_size = var.memory
|
29
|
+
|
30
|
+
environment {
|
31
|
+
variables = var.environment_variables
|
32
|
+
}
|
33
|
+
|
34
|
+
vpc_config {
|
35
|
+
subnet_ids = data.aws_subnets.default_vpc_subnets.ids
|
36
|
+
security_group_ids = local.security_group_ids
|
37
|
+
}
|
38
|
+
|
39
|
+
file_system_config {
|
40
|
+
arn = aws_efs_access_point.lambda_ap.arn
|
41
|
+
local_mount_path = "/mnt/efs"
|
42
|
+
}
|
43
|
+
|
44
|
+
image_config {
|
45
|
+
command = ["app.handler"]
|
46
|
+
}
|
47
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
variable "function_name" {
|
2
|
+
description = "Lambda function name"
|
3
|
+
type = string
|
4
|
+
}
|
5
|
+
variable "timeout" {
|
6
|
+
description = "Timeout for call"
|
7
|
+
type = number
|
8
|
+
default = 30
|
9
|
+
}
|
10
|
+
variable "environment_variables" {
|
11
|
+
type = map(string)
|
12
|
+
description = "A map of environment variables to pass to the resource"
|
13
|
+
default = {}
|
14
|
+
}
|
15
|
+
variable "role_arn" {
|
16
|
+
}
|
17
|
+
variable "image" {
|
18
|
+
}
|
19
|
+
variable "memory" {
|
20
|
+
type = number
|
21
|
+
description = "The memory (MiB) for the task"
|
22
|
+
default = 512
|
23
|
+
}
|
24
|
+
|
25
|
+
variable "network" {
|
26
|
+
description = "Name of the remote state block to use for the network"
|
27
|
+
}
|
28
|
+
|
29
|
+
variable "efs" {
|
30
|
+
description = "Name of the remote state block to use for the EFS"
|
31
|
+
}
|
32
|
+
|
33
|
+
variable "sg_keys" {
|
34
|
+
description = "List of output names in the remote state representing security group IDs"
|
35
|
+
type = list(string)
|
36
|
+
default = ["aws_network_efs_sg_id", "aws_network_ssh_sg_id"]
|
37
|
+
}
|
38
|
+
|
39
|
+
variable "mount_point" {
|
40
|
+
description = "Where to mount the efs drive"
|
41
|
+
type = string
|
42
|
+
default = "/mnt/efs"
|
43
|
+
}
|
44
|
+
|
@@ -6,6 +6,7 @@ resource "aws_key_pair" "this" {
|
|
6
6
|
resource "aws_instance" "this" {
|
7
7
|
ami = data.aws_ami.amazon_linux_2.id
|
8
8
|
instance_type = "t2.micro"
|
9
|
+
iam_instance_profile = var.policies.outputs.ec2_host_profile_id
|
9
10
|
|
10
11
|
key_name = aws_key_pair.this.key_name
|
11
12
|
|
@@ -23,7 +24,7 @@ resource "aws_instance" "this" {
|
|
23
24
|
packages:
|
24
25
|
- amazon-efs-utils
|
25
26
|
runcmd:
|
26
|
-
- mkdir -p
|
27
|
+
- mkdir -p ${var.mount_point}
|
27
28
|
- mount -t efs -o tls ${local.efs_id}:/ ${var.mount_point}
|
28
29
|
- echo "${local.efs_id}:/ ${var.mount_point} efs defaults,_netdev 0 0" >> /etc/fstab
|
29
30
|
EOF
|
@@ -6,15 +6,23 @@ variable "efs" {
|
|
6
6
|
description = "Name of the remote state block to use for the EFS"
|
7
7
|
}
|
8
8
|
|
9
|
+
variable "policies" {
|
10
|
+
description = "Name of the remote state block to use for the policies"
|
11
|
+
}
|
12
|
+
|
9
13
|
variable "sg_keys" {
|
10
14
|
description = "List of output names in the remote state representing security group IDs"
|
11
15
|
type = list(string)
|
12
16
|
default = ["aws_network_efs_sg_id", "aws_network_ssh_sg_id"]
|
13
17
|
}
|
14
|
-
|
15
18
|
variable "mount_point" {
|
16
19
|
description = "Where to mount the efs drive"
|
17
20
|
type = string
|
18
21
|
default = "/mnt/efs"
|
19
22
|
}
|
20
23
|
|
24
|
+
#variable "iam_instance_profile" {
|
25
|
+
# description = "Instance profile"
|
26
|
+
# type = string
|
27
|
+
# default = null
|
28
|
+
#}
|
@@ -4,16 +4,19 @@ resource "aws_ecs_task_definition" "this" {
|
|
4
4
|
network_mode = "awsvpc"
|
5
5
|
cpu = var.cpu
|
6
6
|
memory = var.memory
|
7
|
-
execution_role_arn = var.
|
7
|
+
execution_role_arn = var.policies.outputs.fargate_execution_role_arn
|
8
|
+
task_role_arn = var.policies.outputs.fargate_task_role_arn
|
8
9
|
|
9
10
|
container_definitions = jsonencode([
|
10
11
|
{
|
11
12
|
name = var.container_name
|
12
13
|
image = var.image
|
14
|
+
user = var.user
|
13
15
|
essential = true
|
14
16
|
portMappings = var.port_mappings
|
15
17
|
//entryPoint = var.entry_point
|
16
18
|
command = var.command
|
19
|
+
environment = var.environment
|
17
20
|
|
18
21
|
mountPoints = [
|
19
22
|
{
|
@@ -6,6 +6,10 @@ variable "efs" {
|
|
6
6
|
description = "Name of the remote state block to use for the EFS"
|
7
7
|
}
|
8
8
|
|
9
|
+
variable "policies" {
|
10
|
+
description = "Name of the remote state block to use for the policies"
|
11
|
+
}
|
12
|
+
|
9
13
|
variable "sg_keys" {
|
10
14
|
description = "List of output names in the remote state representing security group IDs"
|
11
15
|
type = list(string)
|
@@ -35,11 +39,6 @@ variable "memory" {
|
|
35
39
|
default = 512
|
36
40
|
}
|
37
41
|
|
38
|
-
variable "role_arn" {
|
39
|
-
type = string
|
40
|
-
description = "ARN of the task execution role"
|
41
|
-
}
|
42
|
-
|
43
42
|
variable "container_name" {
|
44
43
|
type = string
|
45
44
|
description = "Name of the container"
|
@@ -51,6 +50,12 @@ variable "image" {
|
|
51
50
|
description = "Docker image URL for the container"
|
52
51
|
}
|
53
52
|
|
53
|
+
variable "user" {
|
54
|
+
description = "User to use"
|
55
|
+
type = string
|
56
|
+
default = null
|
57
|
+
}
|
58
|
+
|
54
59
|
variable "port_mappings" {
|
55
60
|
type = list(object({
|
56
61
|
containerPort = number
|
@@ -71,3 +76,9 @@ variable "entry_point" {
|
|
71
76
|
description = "Container entry point"
|
72
77
|
default = ["bash"]
|
73
78
|
}
|
79
|
+
|
80
|
+
variable "environment" {
|
81
|
+
type = map(string)
|
82
|
+
description = "A map of environment variables to pass to the resource"
|
83
|
+
default = null
|
84
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
output "arn" {
|
2
|
+
description = "Instance profile arn"
|
3
|
+
value = aws_iam_instance_profile.this.arn
|
4
|
+
}
|
5
|
+
|
6
|
+
output "profile_name" {
|
7
|
+
description = "Instance profile name"
|
8
|
+
value = aws_iam_instance_profile.this.name
|
9
|
+
}
|
10
|
+
|
11
|
+
output "id" {
|
12
|
+
description = "Instance profile id"
|
13
|
+
value = aws_iam_instance_profile.this.id
|
14
|
+
}
|
15
|
+
|
@@ -5,7 +5,7 @@ resource "aws_lambda_function" "this" {
|
|
5
5
|
filename = var.filename
|
6
6
|
source_code_hash = filebase64sha256(var.filename)
|
7
7
|
timeout = var.timeout
|
8
|
-
role = var.
|
8
|
+
role = var.policies.outputs.lambda_execution_role_arn
|
9
9
|
|
10
10
|
environment {
|
11
11
|
variables = var.environment_variables
|
@@ -5,7 +5,7 @@ variable "function_name" {
|
|
5
5
|
variable "runtime" {
|
6
6
|
description = "Ruby runtime"
|
7
7
|
type = string
|
8
|
-
default = "ruby3.
|
8
|
+
default = "ruby3.3"
|
9
9
|
}
|
10
10
|
variable "filename" {
|
11
11
|
description = "ZIP filename with lambda handler"
|
@@ -21,7 +21,6 @@ variable "environment_variables" {
|
|
21
21
|
description = "A map of environment variables to pass to the resource"
|
22
22
|
default = {}
|
23
23
|
}
|
24
|
-
variable "
|
25
|
-
description = "
|
26
|
-
type = string
|
24
|
+
variable "policies" {
|
25
|
+
description = "Name of the remote state block to use for the policies"
|
27
26
|
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
output "arn" {
|
2
|
+
description = "Policy arn"
|
3
|
+
value = aws_iam_policy.this.arn
|
4
|
+
}
|
5
|
+
|
6
|
+
output "name" {
|
7
|
+
description = "Policy name"
|
8
|
+
value = aws_iam_policy.this.name
|
9
|
+
}
|
10
|
+
|
11
|
+
output "id" {
|
12
|
+
description = "Policy id"
|
13
|
+
value = aws_iam_policy.this.id
|
14
|
+
}
|
15
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
variable "policy_name" {
|
2
|
+
type = string
|
3
|
+
}
|
4
|
+
|
5
|
+
variable "statement" {
|
6
|
+
type = list(object({
|
7
|
+
Action = any
|
8
|
+
Effect = string
|
9
|
+
Resource = string
|
10
|
+
}))
|
11
|
+
}
|
12
|
+
|
13
|
+
variable "role" {
|
14
|
+
description = "Role id to which to attach policy"
|
15
|
+
type = string
|
16
|
+
}
|
data/test/scout/aws/test_s3.rb
CHANGED
@@ -7,7 +7,7 @@ class TestS3 < Test::Unit::TestCase
|
|
7
7
|
file = "s3://herlab/tmp/foo.txt"
|
8
8
|
|
9
9
|
Open::S3.write file, "TEST"
|
10
|
-
|
10
|
+
|
11
11
|
dir = "s3://herlab/tmp"
|
12
12
|
|
13
13
|
assert_include Open::S3.glob(dir, "**/*"), file
|
@@ -30,6 +30,19 @@ class TestS3 < Test::Unit::TestCase
|
|
30
30
|
Open::S3.rm uri
|
31
31
|
end
|
32
32
|
|
33
|
+
def test_cp
|
34
|
+
uri = "s3://herlab/tmp/foo.txt"
|
35
|
+
|
36
|
+
Open::S3.write uri, "TEST"
|
37
|
+
io = Open::S3.get_stream uri
|
38
|
+
assert_equal "TEST", io.read
|
39
|
+
TmpFile.with_path do |file|
|
40
|
+
Open.cp uri, file
|
41
|
+
assert_equal "TEST", Open.read(file)
|
42
|
+
end
|
43
|
+
Open::S3.rm uri
|
44
|
+
end
|
45
|
+
|
33
46
|
def test_write_block
|
34
47
|
uri = "s3://herlab/tmp/foo.txt"
|
35
48
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scout-camp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Vazquez
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 2025-04-16 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: scout-essentials
|
@@ -70,6 +70,10 @@ files:
|
|
70
70
|
- share/terraform/aws/cluster/main.tf
|
71
71
|
- share/terraform/aws/cluster/output.tf
|
72
72
|
- share/terraform/aws/cluster/variables.tf
|
73
|
+
- share/terraform/aws/container_lambda/data.tf
|
74
|
+
- share/terraform/aws/container_lambda/locals.tf
|
75
|
+
- share/terraform/aws/container_lambda/main.tf
|
76
|
+
- share/terraform/aws/container_lambda/variables.tf
|
73
77
|
- share/terraform/aws/efs/data.tf
|
74
78
|
- share/terraform/aws/efs/locals.tf
|
75
79
|
- share/terraform/aws/efs/main.tf
|
@@ -87,12 +91,18 @@ files:
|
|
87
91
|
- share/terraform/aws/host/main.tf
|
88
92
|
- share/terraform/aws/host/output.tf
|
89
93
|
- share/terraform/aws/host/variables.tf
|
94
|
+
- share/terraform/aws/iam_instance_profile/main.tf
|
95
|
+
- share/terraform/aws/iam_instance_profile/output.tf
|
96
|
+
- share/terraform/aws/iam_instance_profile/variables.tf
|
90
97
|
- share/terraform/aws/lambda/main.tf
|
91
98
|
- share/terraform/aws/lambda/variables.tf
|
92
99
|
- share/terraform/aws/network/data.tf
|
93
100
|
- share/terraform/aws/network/main.tf
|
94
101
|
- share/terraform/aws/network/output.tf
|
95
102
|
- share/terraform/aws/network/variables.tf
|
103
|
+
- share/terraform/aws/policy/main.tf
|
104
|
+
- share/terraform/aws/policy/output.tf
|
105
|
+
- share/terraform/aws/policy/variables.tf
|
96
106
|
- share/terraform/aws/policy_attachment/main.tf
|
97
107
|
- share/terraform/aws/policy_attachment/variables.tf
|
98
108
|
- share/terraform/aws/provider/data.tf
|
@@ -100,6 +110,8 @@ files:
|
|
100
110
|
- share/terraform/aws/role/main.tf
|
101
111
|
- share/terraform/aws/role/output.tf
|
102
112
|
- share/terraform/aws/role/variables.tf
|
113
|
+
- share/terraform/aws/role_policy/main.tf
|
114
|
+
- share/terraform/aws/role_policy/variables.tf
|
103
115
|
- share/terraform/ssh/cmd/main.tf
|
104
116
|
- share/terraform/ssh/cmd/variables.tf
|
105
117
|
- test/scout/aws/test_s3.rb
|
@@ -127,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
139
|
- !ruby/object:Gem::Version
|
128
140
|
version: '0'
|
129
141
|
requirements: []
|
130
|
-
rubygems_version: 3.6.
|
142
|
+
rubygems_version: 3.6.6
|
131
143
|
specification_version: 4
|
132
144
|
summary: Deploy you scouts
|
133
145
|
test_files: []
|