@intentius/chant-lexicon-terraform 0.100.0 → 0.102.0
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.
- package/dist/codegen/package.d.ts +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/hcl/jsonencode.d.ts +106 -0
- package/dist/hcl/jsonencode.d.ts.map +1 -0
- package/dist/hcl/marker.d.ts.map +1 -1
- package/dist/integrity.json +11 -2
- package/dist/lint/audit-catalog.d.ts.map +1 -1
- package/dist/lint/audit-lineage.d.ts +1 -1
- package/dist/lint/audit-lineage.d.ts.map +1 -1
- package/dist/lint/post-synth/flat-attributes.d.ts +69 -0
- package/dist/lint/post-synth/flat-attributes.d.ts.map +1 -0
- package/dist/lint/post-synth/index.d.ts.map +1 -1
- package/dist/lint/post-synth/tf030.d.ts +51 -0
- package/dist/lint/post-synth/tf030.d.ts.map +1 -0
- package/dist/lint/post-synth/tf031.d.ts +55 -0
- package/dist/lint/post-synth/tf031.d.ts.map +1 -0
- package/dist/lint/post-synth/tf032.d.ts +71 -0
- package/dist/lint/post-synth/tf032.d.ts.map +1 -0
- package/dist/lint/post-synth/tf033.d.ts +50 -0
- package/dist/lint/post-synth/tf033.d.ts.map +1 -0
- package/dist/lint/post-synth/tf034.d.ts +25 -0
- package/dist/lint/post-synth/tf034.d.ts.map +1 -0
- package/dist/lint/post-synth/tf035.d.ts +33 -0
- package/dist/lint/post-synth/tf035.d.ts.map +1 -0
- package/dist/lint/post-synth/tf036.d.ts +33 -0
- package/dist/lint/post-synth/tf036.d.ts.map +1 -0
- package/dist/lint/post-synth/tf037.d.ts +31 -0
- package/dist/lint/post-synth/tf037.d.ts.map +1 -0
- package/dist/manifest.json +1 -1
- package/dist/okf/index.md +8 -0
- package/dist/okf/rules/TF030.md +11 -0
- package/dist/okf/rules/TF031.md +11 -0
- package/dist/okf/rules/TF032.md +11 -0
- package/dist/okf/rules/TF033.md +11 -0
- package/dist/okf/rules/TF034.md +11 -0
- package/dist/okf/rules/TF035.md +11 -0
- package/dist/okf/rules/TF036.md +11 -0
- package/dist/okf/rules/TF037.md +11 -0
- package/dist/op/activity-contracts.d.ts +18 -18
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/rules/flat-attributes.ts +146 -0
- package/dist/rules/tf030.ts +290 -0
- package/dist/rules/tf031.ts +370 -0
- package/dist/rules/tf032.ts +226 -0
- package/dist/rules/tf033.ts +160 -0
- package/dist/rules/tf034.ts +63 -0
- package/dist/rules/tf035.ts +74 -0
- package/dist/rules/tf036.ts +119 -0
- package/dist/rules/tf037.ts +101 -0
- package/package.json +3 -3
- package/src/hcl/jsonencode.test.ts +226 -0
- package/src/hcl/jsonencode.ts +454 -0
- package/src/lint/audit-catalog.ts +148 -0
- package/src/lint/audit-lineage.ts +155 -1
- package/src/lint/post-synth/estate-2284.test.ts +68 -0
- package/src/lint/post-synth/fixtures/TF030/negative-rules.tf +45 -0
- package/src/lint/post-synth/fixtures/TF030/negative.tf +55 -0
- package/src/lint/post-synth/fixtures/TF030/not-determined-port.tf +28 -0
- package/src/lint/post-synth/fixtures/TF030/not-determined-standalone.tf +32 -0
- package/src/lint/post-synth/fixtures/TF030/not-determined-vpc-rule.tf +21 -0
- package/src/lint/post-synth/fixtures/TF030/not-determined.tf +39 -0
- package/src/lint/post-synth/fixtures/TF030/positive-ipv6.tf +44 -0
- package/src/lint/post-synth/fixtures/TF030/positive-mixed.tf +36 -0
- package/src/lint/post-synth/fixtures/TF030/positive-standalone.tf +25 -0
- package/src/lint/post-synth/fixtures/TF030/positive.tf +43 -0
- package/src/lint/post-synth/fixtures/TF031/negative.tf +89 -0
- package/src/lint/post-synth/fixtures/TF031/not-determined.tf +139 -0
- package/src/lint/post-synth/fixtures/TF031/positive-data-source.tf +57 -0
- package/src/lint/post-synth/fixtures/TF031/positive-heredoc.tf +149 -0
- package/src/lint/post-synth/fixtures/TF031/positive-jsonencode.tf +115 -0
- package/src/lint/post-synth/fixtures/TF032/negative-heredoc.tf +20 -0
- package/src/lint/post-synth/fixtures/TF032/negative-references.tf +214 -0
- package/src/lint/post-synth/fixtures/TF032/negative.tf +99 -0
- package/src/lint/post-synth/fixtures/TF032/positive-heredoc.tf +22 -0
- package/src/lint/post-synth/fixtures/TF032/positive-sidecar.tf +197 -0
- package/src/lint/post-synth/fixtures/TF032/positive.tf +54 -0
- package/src/lint/post-synth/fixtures/TF033/negative.tf +39 -0
- package/src/lint/post-synth/fixtures/TF033/not-determined-aurora.tf +25 -0
- package/src/lint/post-synth/fixtures/TF033/positive-absent.tf +93 -0
- package/src/lint/post-synth/fixtures/TF033/positive.tf +50 -0
- package/src/lint/post-synth/fixtures/TF034/negative.tf +24 -0
- package/src/lint/post-synth/fixtures/TF034/positive-absent.tf +36 -0
- package/src/lint/post-synth/fixtures/TF034/positive.tf +14 -0
- package/src/lint/post-synth/fixtures/TF035/negative-absent.tf +43 -0
- package/src/lint/post-synth/fixtures/TF035/negative.tf +54 -0
- package/src/lint/post-synth/fixtures/TF035/positive.tf +37 -0
- package/src/lint/post-synth/fixtures/TF036/negative.tf +61 -0
- package/src/lint/post-synth/fixtures/TF036/not-determined.tf +28 -0
- package/src/lint/post-synth/fixtures/TF036/positive.tf +38 -0
- package/src/lint/post-synth/fixtures/TF037/negative-exclusion.tf +63 -0
- package/src/lint/post-synth/fixtures/TF037/negative.tf +27 -0
- package/src/lint/post-synth/fixtures/TF037/not-determined.tf +27 -0
- package/src/lint/post-synth/fixtures/TF037/positive-absent.tf +15 -0
- package/src/lint/post-synth/fixtures/TF037/positive.tf +26 -0
- package/src/lint/post-synth/fixtures/estate-2284/clean/main.tf +132 -0
- package/src/lint/post-synth/fixtures/estate-2284/violating/main.tf +112 -0
- package/src/lint/post-synth/flat-attributes.ts +146 -0
- package/src/lint/post-synth/index.ts +16 -0
- package/src/lint/post-synth/tf030.test.ts +219 -0
- package/src/lint/post-synth/tf030.ts +290 -0
- package/src/lint/post-synth/tf031.test.ts +229 -0
- package/src/lint/post-synth/tf031.ts +370 -0
- package/src/lint/post-synth/tf032.test.ts +127 -0
- package/src/lint/post-synth/tf032.ts +226 -0
- package/src/lint/post-synth/tf033.test.ts +126 -0
- package/src/lint/post-synth/tf033.ts +160 -0
- package/src/lint/post-synth/tf034.test.ts +71 -0
- package/src/lint/post-synth/tf034.ts +63 -0
- package/src/lint/post-synth/tf035.test.ts +68 -0
- package/src/lint/post-synth/tf035.ts +74 -0
- package/src/lint/post-synth/tf036.test.ts +87 -0
- package/src/lint/post-synth/tf036.ts +119 -0
- package/src/lint/post-synth/tf037.test.ts +88 -0
- package/src/lint/post-synth/tf037.ts +101 -0
- package/src/op/activities/terraform.test.ts +2 -2
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Vendored for TF032 (chant #2287). Source: https://github.com/testdrivenio/django-ecs-terraform
|
|
2
|
+
# Path: terraform/07_ecs.tf
|
|
3
|
+
# Commit: 6571bcce48cee37fa10b1ee9a5caec147356b047
|
|
4
|
+
# Licence: MIT
|
|
5
|
+
# Copyright (c) 2023 TestDriven.io. MIT licence: https://github.com/testdrivenio/django-ecs-terraform/blob/6571bcce48cee37fa10b1ee9a5caec147356b047/LICENSE
|
|
6
|
+
# Copied verbatim below this header. No finding: RDS_PASSWORD is var.rds_password (a reference, not a literal), and the collectstatic task has no environment. The app task's container_definitions is data.template_file.app.rendered, which is not determined.
|
|
7
|
+
|
|
8
|
+
resource "aws_ecs_cluster" "production" {
|
|
9
|
+
name = "${var.ecs_cluster_name}-cluster"
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
data "template_file" "app" {
|
|
13
|
+
template = file("templates/django_app.json.tpl")
|
|
14
|
+
|
|
15
|
+
vars = {
|
|
16
|
+
docker_image_url_django = var.docker_image_url_django
|
|
17
|
+
docker_image_url_nginx = var.docker_image_url_nginx
|
|
18
|
+
region = var.region
|
|
19
|
+
rds_db_name = var.rds_db_name
|
|
20
|
+
rds_username = var.rds_username
|
|
21
|
+
rds_password = var.rds_password
|
|
22
|
+
rds_hostname = aws_db_instance.production.address
|
|
23
|
+
allowed_hosts = var.allowed_hosts
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
resource "aws_ecs_task_definition" "app" {
|
|
28
|
+
family = "django-app"
|
|
29
|
+
depends_on = [aws_db_instance.production]
|
|
30
|
+
network_mode = "awsvpc" # Required for Fargate
|
|
31
|
+
requires_compatibilities = ["FARGATE"]
|
|
32
|
+
cpu = "${var.fargate_cpu}"
|
|
33
|
+
memory = "${var.fargate_memory}"
|
|
34
|
+
execution_role_arn = aws_iam_role.ecs-task-execution-role.arn
|
|
35
|
+
task_role_arn = aws_iam_role.ecs-task-execution-role.arn
|
|
36
|
+
container_definitions = data.template_file.app.rendered
|
|
37
|
+
volume {
|
|
38
|
+
name = "efs-volume"
|
|
39
|
+
efs_volume_configuration {
|
|
40
|
+
file_system_id = aws_efs_file_system.efs.id
|
|
41
|
+
root_directory = "/"
|
|
42
|
+
transit_encryption = "ENABLED"
|
|
43
|
+
transit_encryption_port = 2049
|
|
44
|
+
authorization_config {
|
|
45
|
+
access_point_id = aws_efs_access_point.app_access_point.id
|
|
46
|
+
iam = "ENABLED"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
resource "aws_ecs_service" "production" {
|
|
53
|
+
name = "${var.ecs_cluster_name}-service"
|
|
54
|
+
cluster = aws_ecs_cluster.production.id
|
|
55
|
+
task_definition = aws_ecs_task_definition.app.arn
|
|
56
|
+
launch_type = "FARGATE"
|
|
57
|
+
desired_count = var.app_count
|
|
58
|
+
network_configuration {
|
|
59
|
+
subnets = [aws_subnet.public-subnet-1.id, aws_subnet.public-subnet-2.id]
|
|
60
|
+
security_groups = [aws_security_group.ecs-fargate.id]
|
|
61
|
+
assign_public_ip = true
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
load_balancer {
|
|
65
|
+
target_group_arn = aws_alb_target_group.default-target-group.arn
|
|
66
|
+
container_name = "nginx"
|
|
67
|
+
container_port = 80
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
resource "aws_ecs_task_definition" "django_migration" {
|
|
72
|
+
family = "django-migration-task"
|
|
73
|
+
network_mode = "awsvpc"
|
|
74
|
+
requires_compatibilities = ["FARGATE"]
|
|
75
|
+
cpu = var.fargate_cpu
|
|
76
|
+
memory = var.fargate_memory
|
|
77
|
+
execution_role_arn = aws_iam_role.ecs-task-execution-role.arn
|
|
78
|
+
|
|
79
|
+
container_definitions = jsonencode([
|
|
80
|
+
{
|
|
81
|
+
name = "django-migration-container"
|
|
82
|
+
image = var.docker_image_url_django
|
|
83
|
+
environment: [
|
|
84
|
+
{
|
|
85
|
+
"name": "RDS_DB_NAME",
|
|
86
|
+
"value": var.rds_db_name
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"name": "RDS_USERNAME",
|
|
90
|
+
"value": var.rds_username
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"name": "RDS_PASSWORD",
|
|
94
|
+
"value": var.rds_password
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "RDS_HOSTNAME",
|
|
98
|
+
"value": aws_db_instance.production.address
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"name": "RDS_PORT",
|
|
102
|
+
"value": "5432"
|
|
103
|
+
}
|
|
104
|
+
],
|
|
105
|
+
# Run migrations as the command
|
|
106
|
+
command = ["python", "manage.py", "migrate"]
|
|
107
|
+
|
|
108
|
+
# Add log configuration for CloudWatch
|
|
109
|
+
logConfiguration = {
|
|
110
|
+
logDriver = "awslogs"
|
|
111
|
+
options = {
|
|
112
|
+
awslogs-group = "/ecs/django-app"
|
|
113
|
+
awslogs-region = var.region
|
|
114
|
+
awslogs-stream-prefix = "ecs"
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# Other required configurations go here...
|
|
119
|
+
portMappings = [
|
|
120
|
+
{
|
|
121
|
+
containerPort = 8000
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
])
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
resource "aws_efs_file_system" "efs" {
|
|
129
|
+
lifecycle_policy {
|
|
130
|
+
transition_to_ia = "AFTER_30_DAYS"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
resource "aws_efs_access_point" "app_access_point" {
|
|
135
|
+
file_system_id = aws_efs_file_system.efs.id
|
|
136
|
+
posix_user {
|
|
137
|
+
uid = 1000
|
|
138
|
+
gid = 1000
|
|
139
|
+
}
|
|
140
|
+
root_directory {
|
|
141
|
+
path = "/efs"
|
|
142
|
+
creation_info {
|
|
143
|
+
owner_uid = 1000
|
|
144
|
+
owner_gid = 1000
|
|
145
|
+
permissions = "755"
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
resource "aws_efs_mount_target" "efs_mount" {
|
|
151
|
+
count = length([aws_subnet.public-subnet-1.id, aws_subnet.public-subnet-2.id])
|
|
152
|
+
file_system_id = aws_efs_file_system.efs.id
|
|
153
|
+
subnet_id = [aws_subnet.public-subnet-1.id, aws_subnet.public-subnet-2.id][count.index]
|
|
154
|
+
security_groups = [aws_security_group.efs_sg.id]
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
resource "aws_ecs_task_definition" "django_collectstatic" {
|
|
158
|
+
family = "django-collectstatic-task"
|
|
159
|
+
network_mode = "awsvpc"
|
|
160
|
+
requires_compatibilities = ["FARGATE"]
|
|
161
|
+
cpu = var.fargate_cpu
|
|
162
|
+
memory = var.fargate_memory
|
|
163
|
+
execution_role_arn = aws_iam_role.ecs-task-execution-role.arn
|
|
164
|
+
task_role_arn = aws_iam_role.ecs-task-execution-role.arn
|
|
165
|
+
volume {
|
|
166
|
+
name = "efs-volume"
|
|
167
|
+
efs_volume_configuration {
|
|
168
|
+
file_system_id = aws_efs_file_system.efs.id
|
|
169
|
+
root_directory = "/"
|
|
170
|
+
transit_encryption = "ENABLED"
|
|
171
|
+
transit_encryption_port = 2049
|
|
172
|
+
authorization_config {
|
|
173
|
+
access_point_id = aws_efs_access_point.app_access_point.id
|
|
174
|
+
iam = "ENABLED"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
container_definitions = jsonencode([
|
|
179
|
+
{
|
|
180
|
+
name = "django-collectstatic-container"
|
|
181
|
+
image = var.docker_image_url_django
|
|
182
|
+
linuxParameters = {
|
|
183
|
+
user = "1000:1000"
|
|
184
|
+
},
|
|
185
|
+
# Run collectstatic as the command
|
|
186
|
+
command = ["python", "manage.py", "collectstatic", "--no-input", "-v", "3"]
|
|
187
|
+
|
|
188
|
+
mountPoints = [
|
|
189
|
+
{
|
|
190
|
+
sourceVolume = "efs-volume",
|
|
191
|
+
containerPath = "/efs/staticfiles/",
|
|
192
|
+
readOnly = false
|
|
193
|
+
}
|
|
194
|
+
]
|
|
195
|
+
|
|
196
|
+
# Add log configuration for CloudWatch
|
|
197
|
+
logConfiguration = {
|
|
198
|
+
logDriver = "awslogs"
|
|
199
|
+
options = {
|
|
200
|
+
awslogs-group = "/ecs/django-app"
|
|
201
|
+
awslogs-region = var.region
|
|
202
|
+
awslogs-stream-prefix = "ecs"
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
# Other required configurations go here...
|
|
207
|
+
portMappings = [
|
|
208
|
+
{
|
|
209
|
+
containerPort = 8000
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
])
|
|
214
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Vendored for TF032 (chant #2287). Source: https://github.com/vapor/penny-bot
|
|
2
|
+
# Path: infra/ecs.tf
|
|
3
|
+
# Commit: e1481d187e703649e2116d36c3cb022357946916
|
|
4
|
+
# Licence: Apache-2.0
|
|
5
|
+
# Copyright the penny-bot contributors. Licensed under the Apache License, Version 2.0: https://github.com/vapor/penny-bot/blob/e1481d187e703649e2116d36c3cb022357946916/LICENSE
|
|
6
|
+
# Copied verbatim below this header. Unmodified. Silent: BOT_TOKEN and SO_API_KEY arrive through secrets/valueFrom, and environment holds only a literal stage name and a reference.
|
|
7
|
+
|
|
8
|
+
resource "aws_ecs_cluster" "penny" {
|
|
9
|
+
name = module.constants.ecs_cluster_name
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
resource "aws_ecs_task_definition" "penny" {
|
|
13
|
+
family = "penny-bot"
|
|
14
|
+
skip_destroy = true
|
|
15
|
+
cpu = "256"
|
|
16
|
+
memory = "512"
|
|
17
|
+
network_mode = "awsvpc"
|
|
18
|
+
requires_compatibilities = ["FARGATE"]
|
|
19
|
+
execution_role_arn = data.aws_iam_role.ecs_task_execution.arn
|
|
20
|
+
task_role_arn = data.aws_iam_role.ecs_task.arn
|
|
21
|
+
|
|
22
|
+
runtime_platform {
|
|
23
|
+
cpu_architecture = "ARM64"
|
|
24
|
+
operating_system_family = "LINUX"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
container_definitions = jsonencode([
|
|
28
|
+
{
|
|
29
|
+
name = "penny-bot"
|
|
30
|
+
image = "${aws_ecr_repository.penny_bot_discord_image.repository_url}:${local.penny_image_tag}"
|
|
31
|
+
cpu = 0
|
|
32
|
+
essential = true
|
|
33
|
+
portMappings = []
|
|
34
|
+
mountPoints = []
|
|
35
|
+
volumesFrom = []
|
|
36
|
+
systemControls = []
|
|
37
|
+
environment = [
|
|
38
|
+
{
|
|
39
|
+
name = "DEPLOYMENT_ENVIRONMENT"
|
|
40
|
+
value = "prod"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name = "GH_OAUTH_CLIENT_ID"
|
|
44
|
+
value = module.constants.gh_oauth_client_id
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
secrets = [
|
|
48
|
+
{
|
|
49
|
+
name = "BOT_TOKEN"
|
|
50
|
+
valueFrom = aws_secretsmanager_secret.discord_bot_token.arn
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name = "LOGGING_WEBHOOK_URL"
|
|
54
|
+
valueFrom = aws_secretsmanager_secret.logs_webhook_url.arn
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name = "ACCOUNT_LINKING_OAUTH_FLOW_PRIV_KEY"
|
|
58
|
+
valueFrom = aws_secretsmanager_secret.account_linking_priv_key.arn
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name = "SO_API_KEY"
|
|
62
|
+
valueFrom = aws_secretsmanager_secret.stack_overflow_api_key.arn
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
logConfiguration = {
|
|
66
|
+
logDriver = "awslogs"
|
|
67
|
+
options = {
|
|
68
|
+
awslogs-group = aws_cloudwatch_log_group.ecs_api.name
|
|
69
|
+
awslogs-region = local.region
|
|
70
|
+
awslogs-stream-prefix = "ecs"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
])
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
resource "aws_ecs_service" "penny" {
|
|
78
|
+
name = module.constants.ecs_service_name
|
|
79
|
+
cluster = aws_ecs_cluster.penny.id
|
|
80
|
+
task_definition = "${aws_ecs_task_definition.penny.family}:${aws_ecs_task_definition.penny.revision}"
|
|
81
|
+
desired_count = 1
|
|
82
|
+
launch_type = "FARGATE"
|
|
83
|
+
platform_version = "1.4.0"
|
|
84
|
+
wait_for_steady_state = true
|
|
85
|
+
|
|
86
|
+
deployment_minimum_healthy_percent = 100
|
|
87
|
+
deployment_maximum_percent = 200
|
|
88
|
+
|
|
89
|
+
deployment_circuit_breaker {
|
|
90
|
+
enable = true
|
|
91
|
+
rollback = true
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
network_configuration {
|
|
95
|
+
subnets = data.aws_subnets.default.ids
|
|
96
|
+
security_groups = [aws_security_group.ecs_service.id]
|
|
97
|
+
assign_public_ip = true
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Vendored for TF032 (chant #2287). Source: https://github.com/aquasecurity/trivy-checks
|
|
2
|
+
# Path: checks/cloud/aws/ecs/no_plaintext_secrets.yaml (terraform.bad[0])
|
|
3
|
+
# Commit: 71c05d02845cc2c3a5dfa4fe914a68a052cc88bf
|
|
4
|
+
# Licence: MIT
|
|
5
|
+
# Copyright (c) 2024 Aqua Security. MIT licence: https://github.com/aquasecurity/trivy-checks/blob/71c05d02845cc2c3a5dfa4fe914a68a052cc88bf/LICENSE
|
|
6
|
+
# The upstream check's own failing example, lifted out of its YAML block scalar unchanged.
|
|
7
|
+
# A heredoc with no interpolation arrives from hcl2json as a plain string, so it is read
|
|
8
|
+
# as JSON. Fires once, on DATABASE_PASSWORD.
|
|
9
|
+
|
|
10
|
+
resource "aws_ecs_task_definition" "bad_example" {
|
|
11
|
+
container_definitions = <<EOF
|
|
12
|
+
[
|
|
13
|
+
{
|
|
14
|
+
"name": "my_service",
|
|
15
|
+
"environment": [
|
|
16
|
+
{ "name": "ENVIRONMENT", "value": "development" },
|
|
17
|
+
{ "name": "DATABASE_PASSWORD", "value": "oh no D:"}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
EOF
|
|
22
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Vendored for TF032 (chant #2287). Source: https://github.com/govuk-forms/forms-admin
|
|
2
|
+
# Path: .review_apps/ecs_task_definition.tf
|
|
3
|
+
# Commit: b338d4386619e3379a2555d65b8cfdf5d786905c
|
|
4
|
+
# Licence: MIT
|
|
5
|
+
# Copyright (c) 2022 Crown Copyright (Government Digital Service). MIT licence: https://github.com/govuk-forms/forms-admin/blob/b338d4386619e3379a2555d65b8cfdf5d786905c/LICENSE
|
|
6
|
+
# Copied verbatim below this header. Fires once on the postgres sidecar's literal POSTGRES_PASSWORD; the two containers whose environment is local.forms_admin_env_vars are not determined. The traefik dockerLabels keys are templates, which the reader drops without losing the rest.
|
|
7
|
+
|
|
8
|
+
locals {
|
|
9
|
+
logs_stream_prefix = "${data.terraform_remote_state.review.outputs.review_apps_log_group_name}/pr-${var.pull_request_number}"
|
|
10
|
+
|
|
11
|
+
# try() so that deploys succeed before the review environment state has
|
|
12
|
+
# published the assets outputs
|
|
13
|
+
assets_bucket_name = try(data.terraform_remote_state.review.outputs.assets_bucket_name, "govuk-forms-review-assets")
|
|
14
|
+
forms_admin_task_role_arn = try(data.terraform_remote_state.review.outputs.forms_admin_task_role_arn, null)
|
|
15
|
+
|
|
16
|
+
review_app_hostname = "pr-${var.pull_request_number}.admin.review.forms.service.gov.uk"
|
|
17
|
+
|
|
18
|
+
forms_admin_startup_commands = [
|
|
19
|
+
"echo $PATH",
|
|
20
|
+
"bundle install",
|
|
21
|
+
"echo $PATH",
|
|
22
|
+
"bin/rails db:prepare",
|
|
23
|
+
"bin/rails s -b 0.0.0.0"
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
forms_admin_shell_script = join(" && ", local.forms_admin_startup_commands)
|
|
27
|
+
|
|
28
|
+
forms_admin_env_vars = [
|
|
29
|
+
{ name = "DATABASE_URL", value = "postgres://postgres:postgres@127.0.0.1:5432" },
|
|
30
|
+
{ name = "EMAIL", value = "review-app-submissions@review.forms.service.gov.uk" },
|
|
31
|
+
{ name = "GOVUK_APP_DOMAIN", value = "publishing.service.gov.uk" },
|
|
32
|
+
{ name = "PORT", value = "3000" },
|
|
33
|
+
{ name = "RAILS_DEVELOPMENT_HOSTS", value = "pr-${var.pull_request_number}.admin.review.forms.service.gov.uk" },
|
|
34
|
+
{ name = "RAILS_ENV", value = "production" },
|
|
35
|
+
{ name = "SECRET_KEY_BASE", value = "unsecured_secret_key_material" },
|
|
36
|
+
{ name = "SETTINGS__ACT_AS_USER_ENABLED", value = "true" },
|
|
37
|
+
{ name = "SETTINGS__AUTH_PROVIDER", value = "developer" },
|
|
38
|
+
{ name = "SETTINGS__AWS__ASSETS_S3_BUCKET_NAME", value = local.assets_bucket_name },
|
|
39
|
+
{ name = "SETTINGS__FORMS_ENV", value = "review" },
|
|
40
|
+
{ name = "SETTINGS__FORMS_RUNNER__URL", value = "https://forms.service.gov.uk" },
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
resource "aws_ecs_task_definition" "task" {
|
|
45
|
+
family = "forms-admin-pr-${var.pull_request_number}"
|
|
46
|
+
|
|
47
|
+
network_mode = "awsvpc"
|
|
48
|
+
cpu = 256
|
|
49
|
+
memory = 1024
|
|
50
|
+
|
|
51
|
+
requires_compatibilities = ["FARGATE"]
|
|
52
|
+
|
|
53
|
+
runtime_platform {
|
|
54
|
+
operating_system_family = "LINUX"
|
|
55
|
+
cpu_architecture = "ARM64"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
execution_role_arn = data.terraform_remote_state.review.outputs.ecs_task_execution_role_arn
|
|
59
|
+
|
|
60
|
+
# Gives the app permission to upload brand assets to the assets bucket
|
|
61
|
+
task_role_arn = local.forms_admin_task_role_arn
|
|
62
|
+
|
|
63
|
+
container_definitions = jsonencode([
|
|
64
|
+
|
|
65
|
+
# forms-admin
|
|
66
|
+
{
|
|
67
|
+
name = "forms-admin"
|
|
68
|
+
image = var.forms_admin_container_image
|
|
69
|
+
command = []
|
|
70
|
+
essential = true
|
|
71
|
+
environment = local.forms_admin_env_vars
|
|
72
|
+
# Uploaded files are buffered to tempfiles, and the app user cannot
|
|
73
|
+
# write to a volume mounted at /tmp, so the root filesystem cannot be
|
|
74
|
+
# read-only
|
|
75
|
+
readonlyRootFilesystem = false
|
|
76
|
+
|
|
77
|
+
dockerLabels = {
|
|
78
|
+
"traefik.http.middlewares.forms-admin-pr-${var.pull_request_number}.basicauth.users" : data.terraform_remote_state.review.outputs.traefik_basic_auth_credentials
|
|
79
|
+
|
|
80
|
+
"traefik.http.routers.forms-admin-pr-${var.pull_request_number}.rule" : "Host(`${local.review_app_hostname}`)",
|
|
81
|
+
"traefik.http.routers.forms-admin-pr-${var.pull_request_number}.service" : "forms-admin-pr-${var.pull_request_number}",
|
|
82
|
+
"traefik.http.routers.forms-admin-pr-${var.pull_request_number}.middlewares" : "forms-admin-pr-${var.pull_request_number}@ecs"
|
|
83
|
+
|
|
84
|
+
"traefik.http.services.forms-admin-pr-${var.pull_request_number}.loadbalancer.server.port" : "3000",
|
|
85
|
+
"traefik.http.services.forms-admin-pr-${var.pull_request_number}.loadbalancer.healthcheck.path" : "/up",
|
|
86
|
+
"traefik.enable" : "true",
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
portMappings = [
|
|
90
|
+
{
|
|
91
|
+
containerPort = 3000
|
|
92
|
+
hostPort = 3000
|
|
93
|
+
protocol = "tcp"
|
|
94
|
+
appProtocol = "http"
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
mountPoints = []
|
|
99
|
+
systemControls = []
|
|
100
|
+
volumesFrom = []
|
|
101
|
+
|
|
102
|
+
logConfiguration = {
|
|
103
|
+
logDriver = "awslogs"
|
|
104
|
+
options = {
|
|
105
|
+
awslogs-group = data.terraform_remote_state.review.outputs.review_apps_log_group_name
|
|
106
|
+
awslogs-region = "eu-west-2"
|
|
107
|
+
awslogs-stream-prefix = "${local.logs_stream_prefix}/forms-admin"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
healthCheck = {
|
|
112
|
+
command = ["CMD-SHELL", "wget -O - 'http://localhost:3000/up' || exit 1"]
|
|
113
|
+
interval = 30
|
|
114
|
+
retries = 5
|
|
115
|
+
startPeriod = 180
|
|
116
|
+
timeout = 5
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
dependsOn = [
|
|
120
|
+
{
|
|
121
|
+
containerName = "postgres"
|
|
122
|
+
condition = "HEALTHY"
|
|
123
|
+
}
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
# postgres
|
|
128
|
+
{
|
|
129
|
+
name = "postgres"
|
|
130
|
+
image = "public.ecr.aws/docker/library/postgres:16.6"
|
|
131
|
+
command = []
|
|
132
|
+
essential = true
|
|
133
|
+
|
|
134
|
+
portMappings = [
|
|
135
|
+
{
|
|
136
|
+
containerPort = 5432
|
|
137
|
+
hostPort = 5432
|
|
138
|
+
protocol = "tcp"
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
|
|
142
|
+
mountPoints = []
|
|
143
|
+
systemControls = []
|
|
144
|
+
volumesFrom = []
|
|
145
|
+
|
|
146
|
+
environment = [
|
|
147
|
+
{ name = "POSTGRES_PASSWORD", value = "postgres" }
|
|
148
|
+
]
|
|
149
|
+
|
|
150
|
+
logConfiguration = {
|
|
151
|
+
logDriver = "awslogs"
|
|
152
|
+
options = {
|
|
153
|
+
awslogs-group = data.terraform_remote_state.review.outputs.review_apps_log_group_name
|
|
154
|
+
awslogs-region = "eu-west-2"
|
|
155
|
+
awslogs-stream-prefix = "${local.logs_stream_prefix}/postgres"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
healthCheck = {
|
|
160
|
+
command = ["CMD-SHELL", "psql -h localhost -p 5432 -U postgres -c \"SELECT current_timestamp - pg_postmaster_start_time();\""]
|
|
161
|
+
interval = 30
|
|
162
|
+
retries = 3
|
|
163
|
+
timeout = 5
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
# forms-admin-seeding
|
|
168
|
+
{
|
|
169
|
+
name = "forms-admin-seeding"
|
|
170
|
+
image = var.forms_admin_container_image
|
|
171
|
+
command = ["rake", "db:create", "db:migrate", "db:seed"]
|
|
172
|
+
essential = false
|
|
173
|
+
environment = local.forms_admin_env_vars
|
|
174
|
+
readonlyRootFilesystem = true
|
|
175
|
+
|
|
176
|
+
mountPoints = []
|
|
177
|
+
systemControls = []
|
|
178
|
+
volumesFrom = []
|
|
179
|
+
|
|
180
|
+
logConfiguration = {
|
|
181
|
+
logDriver = "awslogs"
|
|
182
|
+
options = {
|
|
183
|
+
awslogs-group = data.terraform_remote_state.review.outputs.review_apps_log_group_name
|
|
184
|
+
awslogs-region = "eu-west-2"
|
|
185
|
+
awslogs-stream-prefix = "${local.logs_stream_prefix}/forms-admin-seeding"
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
dependsOn = [
|
|
190
|
+
{
|
|
191
|
+
containerName = "postgres"
|
|
192
|
+
condition = "HEALTHY"
|
|
193
|
+
}
|
|
194
|
+
]
|
|
195
|
+
},
|
|
196
|
+
])
|
|
197
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Vendored for TF032 (chant #2287). Source: https://github.com/edstem-tech/paylink-platform
|
|
2
|
+
# Path: terraform/ecs.tf
|
|
3
|
+
# Commit: 2bbcbcce09434286cf90d20f69df0bd3ffa4cd00
|
|
4
|
+
# Licence: MIT
|
|
5
|
+
# Copyright (c) 2025 EdStem. MIT licence: permission notice at https://github.com/edstem-tech/paylink-platform/blob/2bbcbcce09434286cf90d20f69df0bd3ffa4cd00/LICENSE
|
|
6
|
+
# Copied verbatim below this header. Fires twice: DB_PASSWORD and PAYMENT_API_KEY are literals in environment.
|
|
7
|
+
|
|
8
|
+
resource "aws_ecs_cluster" "main" {
|
|
9
|
+
name = "paylink-prod"
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
resource "aws_ecs_task_definition" "api" {
|
|
13
|
+
family = "paylink-api"
|
|
14
|
+
network_mode = "awsvpc"
|
|
15
|
+
requires_compatibilities = ["FARGATE"]
|
|
16
|
+
cpu = "1024"
|
|
17
|
+
memory = "2048"
|
|
18
|
+
task_role_arn = aws_iam_role.task.arn
|
|
19
|
+
execution_role_arn = aws_iam_role.execution.arn
|
|
20
|
+
|
|
21
|
+
container_definitions = jsonencode([{
|
|
22
|
+
name = "api"
|
|
23
|
+
image = "${var.ecr_repo}:latest"
|
|
24
|
+
|
|
25
|
+
portMappings = [{ containerPort = 8080 }]
|
|
26
|
+
|
|
27
|
+
environment = [
|
|
28
|
+
{ name = "SPRING_PROFILES_ACTIVE", value = "prod" },
|
|
29
|
+
{ name = "DB_PASSWORD", value = "Pl-Pr0d-Db-2025!" },
|
|
30
|
+
{ name = "PAYMENT_API_KEY", value = "pk_live_4RtYuIoP2aSdF6gH8jK" }
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
healthCheck = {
|
|
34
|
+
command = ["CMD-SHELL", "curl -f http://localhost:8080/actuator/health || exit 1"]
|
|
35
|
+
interval = 10
|
|
36
|
+
timeout = 2
|
|
37
|
+
retries = 3
|
|
38
|
+
}
|
|
39
|
+
}])
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
resource "aws_ecs_service" "api" {
|
|
43
|
+
name = "paylink-api"
|
|
44
|
+
cluster = aws_ecs_cluster.main.id
|
|
45
|
+
task_definition = aws_ecs_task_definition.api.arn
|
|
46
|
+
desired_count = 2
|
|
47
|
+
launch_type = "FARGATE"
|
|
48
|
+
|
|
49
|
+
network_configuration {
|
|
50
|
+
subnets = aws_subnet.public[*].id
|
|
51
|
+
security_groups = [aws_security_group.service.id]
|
|
52
|
+
assign_public_ip = true
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Vendored for TF033 (chant #2288) from https://github.com/tmknom/example-pragmatic-terraform
|
|
2
|
+
# Path: 13/4.tf
|
|
3
|
+
# Commit: 7043f9216cf7fb55b3c5e9cd1926fe5da04a3ddb
|
|
4
|
+
# Licence: Apache-2.0, https://github.com/tmknom/example-pragmatic-terraform/blob/7043f9216cf7fb55b3c5e9cd1926fe5da04a3ddb/LICENSE
|
|
5
|
+
# The whole file, unmodified.
|
|
6
|
+
#
|
|
7
|
+
# TF033: silent. A MySQL DB instance with storage_encrypted = true and a customer managed kms_key_id.
|
|
8
|
+
|
|
9
|
+
resource "aws_db_instance" "example" {
|
|
10
|
+
identifier = "example"
|
|
11
|
+
engine = "mysql"
|
|
12
|
+
engine_version = "5.7.25"
|
|
13
|
+
instance_class = "db.t3.small"
|
|
14
|
+
allocated_storage = 20
|
|
15
|
+
max_allocated_storage = 100
|
|
16
|
+
storage_type = "gp2"
|
|
17
|
+
storage_encrypted = true
|
|
18
|
+
kms_key_id = aws_kms_key.example.arn
|
|
19
|
+
username = "admin"
|
|
20
|
+
password = "VeryStrongPassword!"
|
|
21
|
+
multi_az = true
|
|
22
|
+
publicly_accessible = false
|
|
23
|
+
backup_window = "09:10-09:40"
|
|
24
|
+
backup_retention_period = 30
|
|
25
|
+
maintenance_window = "mon:10:10-mon:10:40"
|
|
26
|
+
auto_minor_version_upgrade = false
|
|
27
|
+
deletion_protection = true
|
|
28
|
+
skip_final_snapshot = false
|
|
29
|
+
port = 3306
|
|
30
|
+
apply_immediately = false
|
|
31
|
+
vpc_security_group_ids = [module.mysql_sg.security_group_id]
|
|
32
|
+
parameter_group_name = aws_db_parameter_group.example.name
|
|
33
|
+
option_group_name = aws_db_option_group.example.name
|
|
34
|
+
db_subnet_group_name = aws_db_subnet_group.example.name
|
|
35
|
+
|
|
36
|
+
lifecycle {
|
|
37
|
+
ignore_changes = [password]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Vendored for TF033 (chant #2288) from https://github.com/bridgecrewio/terragoat
|
|
2
|
+
# Path: terraform/aws/rds.tf
|
|
3
|
+
# Commit: 729f8da62c6a85ce4af5ad3d123de97776d954c4
|
|
4
|
+
# Licence: Apache-2.0, https://github.com/bridgecrewio/terragoat/blob/729f8da62c6a85ce4af5ad3d123de97776d954c4/LICENSE
|
|
5
|
+
# Excerpt: lines 1-15, unmodified.
|
|
6
|
+
#
|
|
7
|
+
# TF033: one info, Not determined. An aws_rds_cluster with no engine (Aurora; provider v5 defaulted it to "aurora")
|
|
8
|
+
# and no storage_encrypted. AWS encrypts Aurora clusters created on or after 2026-02-16 whatever the
|
|
9
|
+
# configuration says, and the configuration does not say when this one was created.
|
|
10
|
+
|
|
11
|
+
resource "aws_rds_cluster" "app1-rds-cluster" {
|
|
12
|
+
cluster_identifier = "app1-rds-cluster"
|
|
13
|
+
allocated_storage = 10
|
|
14
|
+
backup_retention_period = 0
|
|
15
|
+
tags = {
|
|
16
|
+
git_commit = "079fe74f6b96d887c245664fbd8cf676c92f20e5"
|
|
17
|
+
git_file = "terraform/aws/rds.tf"
|
|
18
|
+
git_last_modified_at = "2021-12-08 23:26:32"
|
|
19
|
+
git_last_modified_by = "tron47@gmail.com"
|
|
20
|
+
git_modifiers = "tron47"
|
|
21
|
+
git_org = "matansha"
|
|
22
|
+
git_repo = "terragoat"
|
|
23
|
+
yor_trace = "b6f2c2ec-0715-46a0-83d4-502e588826d1"
|
|
24
|
+
}
|
|
25
|
+
}
|