scout-camp 0.1.6 → 0.1.10
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 +63 -7
- data/VERSION +1 -1
- data/lib/scout/aws/s3.rb +54 -12
- data/lib/scout/offsite/resource.rb +34 -0
- data/lib/scout/offsite/ssh.rb +2 -0
- data/lib/scout/offsite/sync.rb +2 -0
- data/lib/scout/terraform_dsl/util.rb +2 -2
- data/lib/scout/terraform_dsl.rb +58 -0
- data/lib/scout-camp.rb +1 -0
- data/scout-camp.gemspec +37 -4
- data/scout_commands/sync +33 -0
- data/scout_commands/terraform/lambda_task +9 -5
- data/scout_commands/terraform/list +11 -3
- data/scout_commands/terraform/outputs +33 -0
- data/share/aws/lambda_function.rb +34 -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/data.tf +12 -0
- data/share/terraform/aws/efs/locals.tf +6 -0
- data/share/terraform/aws/efs/main.tf +14 -0
- data/share/terraform/aws/efs/output.tf +3 -0
- data/share/terraform/aws/efs/variables.tf +9 -0
- data/share/terraform/aws/efs_host/data.tf +11 -0
- data/share/terraform/aws/efs_host/locals.tf +8 -0
- data/share/terraform/aws/efs_host/main.tf +32 -0
- data/share/terraform/aws/efs_host/output.tf +3 -0
- data/share/terraform/aws/efs_host/variables.tf +28 -0
- data/share/terraform/aws/fargate/locals.tf +8 -0
- data/share/terraform/aws/fargate/main.tf +41 -0
- data/share/terraform/aws/fargate/variables.tf +84 -0
- 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/network/data.tf +15 -0
- data/share/terraform/aws/network/main.tf +41 -0
- data/share/terraform/aws/network/output.tf +7 -0
- data/share/terraform/aws/network/variables.tf +0 -0
- 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
- data/test/scout/offsite/test_resource.rb +46 -0
- data/test/scout/offsite/test_sync.rb +1 -0
- metadata +36 -3
@@ -7,21 +7,48 @@ def lambda_handler(event:, context:)
|
|
7
7
|
require 'scout/workflow'
|
8
8
|
require 'scout/aws/s3'
|
9
9
|
|
10
|
-
workflow, task_name, jobname, inputs = IndiferentHash.process_options event,
|
11
|
-
|
12
|
-
|
13
|
-
raise
|
14
|
-
|
10
|
+
workflow, task_name, jobname, inputs, clean, queue = IndiferentHash.process_options event,
|
11
|
+
:workflow, :task_name, :jobname, :inputs, :clean, :queue
|
12
|
+
|
13
|
+
raise ParameterException, "No workflow specified" if workflow.nil?
|
14
|
+
|
15
15
|
workflow = Workflow.require_workflow workflow
|
16
16
|
|
17
17
|
case task_name
|
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)
|
25
|
-
|
25
|
+
|
26
|
+
case clean
|
27
|
+
when true, 'true'
|
28
|
+
job.clean
|
29
|
+
when 'recursive'
|
30
|
+
job.recursive_clean
|
31
|
+
end
|
32
|
+
|
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
|
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
|
26
53
|
end
|
27
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
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Get default VPC (optional if you want to restrict to default VPC)
|
2
|
+
data "aws_vpc" "default" {
|
3
|
+
default = true
|
4
|
+
}
|
5
|
+
|
6
|
+
# Get all subnets in the region (filtered to default VPC if needed)
|
7
|
+
data "aws_subnets" "all" {
|
8
|
+
filter {
|
9
|
+
name = "vpc-id"
|
10
|
+
values = [data.aws_vpc.default.id]
|
11
|
+
}
|
12
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
resource "aws_efs_file_system" "this" {
|
2
|
+
creation_token = "herlab-efs"
|
3
|
+
tags = {
|
4
|
+
Name = "HERLab main EFS"
|
5
|
+
}
|
6
|
+
}
|
7
|
+
|
8
|
+
resource "aws_efs_mount_target" "this" {
|
9
|
+
for_each = toset(data.aws_subnets.all.ids)
|
10
|
+
|
11
|
+
file_system_id = aws_efs_file_system.this.id
|
12
|
+
subnet_id = each.value
|
13
|
+
security_groups = local.security_group_ids
|
14
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
resource "aws_key_pair" "this" {
|
2
|
+
key_name = "my-key"
|
3
|
+
public_key = file("~/.ssh/id_rsa.pub") # Adjust if your key is elsewhere
|
4
|
+
}
|
5
|
+
|
6
|
+
resource "aws_instance" "this" {
|
7
|
+
ami = data.aws_ami.amazon_linux_2.id
|
8
|
+
instance_type = "t2.micro"
|
9
|
+
iam_instance_profile = var.policies.outputs.ec2_host_profile_id
|
10
|
+
|
11
|
+
key_name = aws_key_pair.this.key_name
|
12
|
+
|
13
|
+
tags = {
|
14
|
+
Name = "EFS-Service"
|
15
|
+
}
|
16
|
+
|
17
|
+
# Open port 22 for SSH
|
18
|
+
vpc_security_group_ids = local.security_group_ids
|
19
|
+
|
20
|
+
user_data = <<-EOF
|
21
|
+
#cloud-config
|
22
|
+
package_update: true
|
23
|
+
package_upgrade: true
|
24
|
+
packages:
|
25
|
+
- amazon-efs-utils
|
26
|
+
runcmd:
|
27
|
+
- mkdir -p ${var.mount_point}
|
28
|
+
- mount -t efs -o tls ${local.efs_id}:/ ${var.mount_point}
|
29
|
+
- echo "${local.efs_id}:/ ${var.mount_point} efs defaults,_netdev 0 0" >> /etc/fstab
|
30
|
+
EOF
|
31
|
+
}
|
32
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
variable "network" {
|
2
|
+
description = "Name of the remote state block to use for the network"
|
3
|
+
}
|
4
|
+
|
5
|
+
variable "efs" {
|
6
|
+
description = "Name of the remote state block to use for the EFS"
|
7
|
+
}
|
8
|
+
|
9
|
+
variable "policies" {
|
10
|
+
description = "Name of the remote state block to use for the policies"
|
11
|
+
}
|
12
|
+
|
13
|
+
variable "sg_keys" {
|
14
|
+
description = "List of output names in the remote state representing security group IDs"
|
15
|
+
type = list(string)
|
16
|
+
default = ["aws_network_efs_sg_id", "aws_network_ssh_sg_id"]
|
17
|
+
}
|
18
|
+
variable "mount_point" {
|
19
|
+
description = "Where to mount the efs drive"
|
20
|
+
type = string
|
21
|
+
default = "/mnt/efs"
|
22
|
+
}
|
23
|
+
|
24
|
+
#variable "iam_instance_profile" {
|
25
|
+
# description = "Instance profile"
|
26
|
+
# type = string
|
27
|
+
# default = null
|
28
|
+
#}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
resource "aws_ecs_task_definition" "this" {
|
2
|
+
family = var.task_family
|
3
|
+
requires_compatibilities = ["FARGATE"]
|
4
|
+
network_mode = "awsvpc"
|
5
|
+
cpu = var.cpu
|
6
|
+
memory = var.memory
|
7
|
+
execution_role_arn = var.policies.outputs.fargate_execution_role_arn
|
8
|
+
task_role_arn = var.policies.outputs.fargate_task_role_arn
|
9
|
+
|
10
|
+
container_definitions = jsonencode([
|
11
|
+
{
|
12
|
+
name = var.container_name
|
13
|
+
image = var.image
|
14
|
+
user = var.user
|
15
|
+
essential = true
|
16
|
+
portMappings = var.port_mappings
|
17
|
+
//entryPoint = var.entry_point
|
18
|
+
command = var.command
|
19
|
+
environment = var.environment
|
20
|
+
|
21
|
+
mountPoints = [
|
22
|
+
{
|
23
|
+
sourceVolume = "efs-volume"
|
24
|
+
containerPath = var.mount_point
|
25
|
+
}
|
26
|
+
]
|
27
|
+
}
|
28
|
+
])
|
29
|
+
|
30
|
+
volume {
|
31
|
+
name = "efs-volume"
|
32
|
+
efs_volume_configuration {
|
33
|
+
file_system_id = local.efs_id
|
34
|
+
root_directory = "/"
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
resource "aws_ecs_cluster" "this" {
|
40
|
+
name = "${var.task_family}_cluster"
|
41
|
+
}
|
@@ -0,0 +1,84 @@
|
|
1
|
+
variable "network" {
|
2
|
+
description = "Name of the remote state block to use for the network"
|
3
|
+
}
|
4
|
+
|
5
|
+
variable "efs" {
|
6
|
+
description = "Name of the remote state block to use for the EFS"
|
7
|
+
}
|
8
|
+
|
9
|
+
variable "policies" {
|
10
|
+
description = "Name of the remote state block to use for the policies"
|
11
|
+
}
|
12
|
+
|
13
|
+
variable "sg_keys" {
|
14
|
+
description = "List of output names in the remote state representing security group IDs"
|
15
|
+
type = list(string)
|
16
|
+
default = ["aws_network_efs_sg_id", "aws_network_ssh_sg_id"]
|
17
|
+
}
|
18
|
+
|
19
|
+
variable "mount_point" {
|
20
|
+
description = "Where to mount the efs drive"
|
21
|
+
type = string
|
22
|
+
default = "/mnt/efs"
|
23
|
+
}
|
24
|
+
|
25
|
+
variable "task_family" {
|
26
|
+
type = string
|
27
|
+
description = "The family name of the ECS task definition"
|
28
|
+
}
|
29
|
+
|
30
|
+
variable "cpu" {
|
31
|
+
type = number
|
32
|
+
description = "The CPU units for the task"
|
33
|
+
default = 256
|
34
|
+
}
|
35
|
+
|
36
|
+
variable "memory" {
|
37
|
+
type = number
|
38
|
+
description = "The memory (MiB) for the task"
|
39
|
+
default = 512
|
40
|
+
}
|
41
|
+
|
42
|
+
variable "container_name" {
|
43
|
+
type = string
|
44
|
+
description = "Name of the container"
|
45
|
+
default = "app"
|
46
|
+
}
|
47
|
+
|
48
|
+
variable "image" {
|
49
|
+
type = string
|
50
|
+
description = "Docker image URL for the container"
|
51
|
+
}
|
52
|
+
|
53
|
+
variable "user" {
|
54
|
+
description = "User to use"
|
55
|
+
type = string
|
56
|
+
default = null
|
57
|
+
}
|
58
|
+
|
59
|
+
variable "port_mappings" {
|
60
|
+
type = list(object({
|
61
|
+
containerPort = number
|
62
|
+
hostPort = number
|
63
|
+
protocol = string
|
64
|
+
}))
|
65
|
+
description = "List of port mappings for the container"
|
66
|
+
default = []
|
67
|
+
}
|
68
|
+
|
69
|
+
variable "command" {
|
70
|
+
type = list(string)
|
71
|
+
description = "Command to run"
|
72
|
+
}
|
73
|
+
|
74
|
+
variable "entry_point" {
|
75
|
+
type = list(string)
|
76
|
+
description = "Container entry point"
|
77
|
+
default = ["bash"]
|
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,41 @@
|
|
1
|
+
resource "aws_security_group" "efs" {
|
2
|
+
name = "efs-sg"
|
3
|
+
description = "Allow NFS"
|
4
|
+
|
5
|
+
ingress {
|
6
|
+
from_port = 2049
|
7
|
+
to_port = 2049
|
8
|
+
protocol = "tcp"
|
9
|
+
cidr_blocks = ["0.0.0.0/0"]
|
10
|
+
}
|
11
|
+
|
12
|
+
egress {
|
13
|
+
from_port = 0
|
14
|
+
to_port = 0
|
15
|
+
protocol = "-1"
|
16
|
+
cidr_blocks = ["0.0.0.0/0"]
|
17
|
+
}
|
18
|
+
|
19
|
+
tags = {
|
20
|
+
Name = "efs-sg"
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
resource "aws_security_group" "ssh" {
|
25
|
+
name = "allow_ssh"
|
26
|
+
description = "Allow SSH inbound traffic"
|
27
|
+
|
28
|
+
ingress {
|
29
|
+
from_port = 22
|
30
|
+
to_port = 22
|
31
|
+
protocol = "tcp"
|
32
|
+
cidr_blocks = ["0.0.0.0/0"] # WARNING: open to the world. Limit this for production.
|
33
|
+
}
|
34
|
+
|
35
|
+
egress {
|
36
|
+
from_port = 0
|
37
|
+
to_port = 0
|
38
|
+
protocol = "-1"
|
39
|
+
cidr_blocks = ["0.0.0.0/0"]
|
40
|
+
}
|
41
|
+
}
|
File without changes
|
@@ -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
|
+
|