Skip to content

Commit 59c8ad0

Browse files
authored
Ecs waf lb fixes (#93)
* Adding WAF for ECS * Minor fixes for ELB
1 parent c562023 commit 59c8ad0

File tree

11 files changed

+729
-5
lines changed

11 files changed

+729
-5
lines changed

README.md

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ jobs:
5757
1. [VPC](#vpc-inputs)
5858
1. [AWS Route53 Domains and Certificates](#aws-route53-domains-and-certificate-inputs)
5959
1. [Load Balancer](#load-balancer-inputs)
60+
1. [WAF](#waf)
6061
1. [EFS](#efs-inputs)
6162
1. [RDS](#rds-inputs)
6263
1. [Amazon Aurora Inputs](#aurora-inputs)
@@ -210,9 +211,32 @@ The following inputs can be used as `step.with` keys
210211
<hr/>
211212
<br/>
212213

213-
#### **EFS Inputs**
214+
#### **WAF**
214215
| Name | Type | Description |
215216
|------------------|---------|------------------------------------|
217+
| `aws_waf_enable` | Boolean | Enable WAF for load balancer (LB only - NOT ELB). Default is `false` |
218+
| `aws_waf_logging_enable`| Boolean | Enable WAF logging to CloudWatch. Default `false` |
219+
| `aws_waf_log_retention_days`| Number | CloudWatch log retention period for WAF logs. Default `30` |
220+
| `aws_waf_rule_rate_limit`| String | Rate limit for WAF rules. Default is `2000` |
221+
| `aws_waf_rule_managed_rules`| Boolean | Enable common managed rule groups to use. Default `false` |
222+
| `aws_waf_rule_managed_bad_inputs`| Boolean | Enable managed rule for bad inputs. Default `false` |
223+
| `aws_waf_rule_ip_reputation`| Boolean | Enable managed rule for IP reputation. Default `false` |
224+
| `aws_waf_rule_anonymous_ip`| Boolean | Enable managed rule for anonymous IP. Default `false` |
225+
| `aws_waf_rule_bot_control`| Boolean | Enable managed rule for bot control (costs extra). Default `false` |
226+
| `aws_waf_rule_geo_block_countries`| String | Comma separated list of countries to block. |
227+
| `aws_waf_rule_geo_allow_only_countries`| String | Comma separated list of countries to allow. |
228+
| `aws_waf_rule_sqli`| Boolean | Enable managed rule for SQL injection. Default `false` |
229+
| `aws_waf_rule_linux`| Boolean | Enable managed rule for Linux. Default `false` |
230+
| `aws_waf_rule_unix`| Boolean | Enable managed rule for Unix. Default `false` |
231+
| `aws_waf_rule_admin_protection`| Boolean | Enable managed rule for admin protection. Default `false` |
232+
| `aws_waf_rule_user_arn`| String | String of the user created ARN set of rules. |
233+
| `aws_waf_additional_tags`| String | A list of strings that will be added to created resources. Default `"{}"` |
234+
<hr/>
235+
<br/>
236+
237+
#### **EFS Inputs**
238+
| Name | Type | Descrifption |
239+
|------------------|---------|------------------------------------|
216240
| `aws_efs_create` | Boolean | Toggle to indicate whether to create an EFS volume and mount it to the EC2 instance as a part of the provisioning. Note: The stack will manage the EFS and will be destroyed along with the stack. |
217241
| `aws_efs_fs_id` | String | ID of existing EFS volume if you wish to use an existing one. |
218242
| `aws_efs_create_mount_target` | String | Toggle to indicate whether we should create a mount target for the EFS volume or not. Defaults to `true`.|
@@ -457,7 +481,7 @@ The following inputs can be used as `step.with` keys
457481
| `aws_ecr_repo_read_arn` | String | The ARNs of the IAM users/roles that have read access to the repository. (Comma separated list)' |
458482
| `aws_ecr_repo_write_arn` | String | The ARNs of the IAM users/roles that have read/write access to the repository. (Comma separated list)' |
459483
| `aws_ecr_repo_read_arn_lambda` | String | The ARNs of the Lambda service roles that have read access to the repository. (Comma separated list)' |
460-
| `aws_ecr_lifecycle_policy_input` | String | The policy document. This is a JSON formatted string. See more details about [Policy Parameters](http://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html#lifecycle_policy_parameters) in the official AWS docs' |
484+
| `aws_ecr_lifecycle_policy_input` | JSON | The policy document. This is a JSON formatted string. See more details about [Policy Parameters](http://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html#lifecycle_policy_parameters) in the official AWS docs' |
461485
| `aws_ecr_public_repo_catalog` | String | Catalog data configuration for the repository. Defaults to `{}`.' |
462486
| `aws_ecr_registry_policy_input` | String | The policy document. This is a JSON formatted string' |
463487
| `aws_ecr_additional_tags ` | JSON | Add additional tags to the terraform [default tags](https://www.hashicorp.com/blog/default-tags-in-the-terraform-aws-provider), any tags put here will be added to ECR provisioned resources.|
@@ -731,4 +755,4 @@ We would love for you to contribute to [bitovi/github-actions-deploy-docker-to-e
731755
Would you like to see additional features? [Create an issue](https://github.com/bitovi/github-actions-deploy-docker-to-ec2/issues/new) or a [Pull Requests](https://github.com/bitovi/github-actions-deploy-docker-to-ec2/pulls). We love discussing solutions!
732756

733757
## License
734-
The scripts and documentation in this project are released under the [MIT License](https://github.com/bitovi/github-actions-deploy-docker-to-ec2/blob/main/LICENSE).
758+
The scripts and documentation in this project are released under the [MIT License](https://github.com/bitovi/github-actions-deploy-docker-to-ec2/blob/main/LICENSE).

action.yaml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,59 @@ inputs:
280280
description: 'A JSON object of additional tags that will be included on created resources. Example: `{"key1": "value1", "key2": "value2"}`'
281281
required: false
282282

283+
# AWS WAF
284+
aws_waf_enable:
285+
description: 'Enable WAF for load balancer.'
286+
required: false
287+
aws_waf_logging_enable:
288+
description: 'Enable WAF logging to CloudWatch.'
289+
required: false
290+
aws_waf_log_retention_days:
291+
description: 'CloudWatch log retention period for WAF logs.'
292+
required: false
293+
aws_waf_rule_rate_limit:
294+
description: 'Rate limit for WAF rules.'
295+
required: false
296+
aws_waf_rule_managed_rules:
297+
description: 'Enable common managed rule groups to use.'
298+
required: false
299+
aws_waf_rule_managed_bad_inputs:
300+
description: 'Enable managed rule for bad inputs.'
301+
required: false
302+
aws_waf_rule_ip_reputation:
303+
description: 'Enable managed rule for IP reputation.'
304+
required: false
305+
aws_waf_rule_anonymous_ip:
306+
description: 'Enable managed rule for anonymous IP.'
307+
required: false
308+
aws_waf_rule_bot_control:
309+
description: 'Enable managed rule for bot control (costs extra).'
310+
required: false
311+
aws_waf_rule_geo_block_countries:
312+
description: 'Comma separated list of countries to block.'
313+
required: false
314+
aws_waf_rule_geo_allow_only_countries:
315+
description: 'Comma separated list of countries to allow.'
316+
required: false
317+
aws_waf_rule_sqli:
318+
description: 'Enable managed rule for SQL injection.'
319+
required: false
320+
aws_waf_rule_linux:
321+
description: 'Enable managed rule for Linux.'
322+
required: false
323+
aws_waf_rule_unix:
324+
description: 'Enable managed rule for Unix.'
325+
required: false
326+
aws_waf_rule_admin_protection:
327+
description: 'Enable managed rule for admin protection.'
328+
required: false
329+
aws_waf_rule_user_arn:
330+
description: 'ARN of the user rule.'
331+
required: false
332+
aws_waf_additional_tags:
333+
description: 'A JSON object of additional tags that will be included on created resources. Example: `{"key1": "value1", "key2": "value2"}`'
334+
required: false
335+
283336
# AWS EFS
284337
aws_efs_create:
285338
description: 'Toggle to indicate whether to create and EFS and mount it to the ec2 as a part of the provisioning. Note: The EFS will be managed by the stack and will be destroyed along with the stack.'
@@ -1200,6 +1253,25 @@ runs:
12001253
AWS_ELB_ACCESS_LOG_EXPIRE: ${{ inputs.aws_elb_access_log_expire }}
12011254
AWS_ELB_ADDITIONAL_TAGS: ${{ inputs.aws_elb_additional_tags }}
12021255

1256+
# AWS WAF
1257+
AWS_WAF_ENABLE: ${{ inputs.aws_waf_enable }}
1258+
AWS_WAF_LOGGING_ENABLE: ${{ inputs.aws_waf_logging_enable }}
1259+
AWS_WAF_LOG_RETENTION_DAYS: ${{ inputs.aws_waf_log_retention_days }}
1260+
AWS_WAF_ADDITIONAL_TAGS: ${{ inputs.aws_waf_additional_tags }}
1261+
AWS_WAF_RULE_RATE_LIMIT: ${{ inputs.aws_waf_rule_rate_limit }}
1262+
AWS_WAF_RULE_MANAGED_RULES: ${{ inputs.aws_waf_rule_managed_rules }}
1263+
AWS_WAF_RULE_MANAGED_BAD_INPUTS: ${{ inputs.aws_waf_rule_managed_bad_inputs }}
1264+
AWS_WAF_RULE_IP_REPUTATION: ${{ inputs.aws_waf_rule_ip_reputation }}
1265+
AWS_WAF_RULE_ANONYMOUS_IP: ${{ inputs.aws_waf_rule_anonymous_ip }}
1266+
AWS_WAF_RULE_BOT_CONTROL: ${{ inputs.aws_waf_rule_bot_control }}
1267+
AWS_WAF_RULE_GEO_BLOCK_COUNTRIES: ${{ inputs.aws_waf_rule_geo_block_countries }}
1268+
AWS_WAF_RULE_GEO_ALLOW_ONLY_COUNTRIES: ${{ inputs.aws_waf_rule_geo_allow_only_countries }}
1269+
AWS_WAF_RULE_USER_ARN: ${{ inputs.aws_waf_rule_user_arn }}
1270+
AWS_WAF_RULE_SQLI: ${{ inputs.aws_waf_rule_sqli }}
1271+
AWS_WAF_RULE_LINUX: ${{ inputs.aws_waf_rule_linux }}
1272+
AWS_WAF_RULE_UNIX: ${{ inputs.aws_waf_rule_unix }}
1273+
AWS_WAF_RULE_ADMIN_PROTECTION: ${{ inputs.aws_waf_rule_admin_protection }}
1274+
12031275
# AWS EFS
12041276
AWS_EFS_CREATE: ${{ inputs.aws_efs_create }}
12051277
AWS_EFS_FS_ID: ${{ inputs.aws_efs_fs_id }}

operations/_scripts/generate/generate_provider.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,6 @@ provider \"kubernetes\" {
7474
}" >> "${GITHUB_ACTION_PATH}/operations/deployment/terraform/$1/bitovi_provider.tf"
7575
}
7676

77-
generate_provider_aws aws ec2,r53,elb,efs,vpc,rds,aurora,ecs,db_proxy,redis,eks,ecr
77+
generate_provider_aws aws ec2,r53,elb,efs,vpc,rds,aurora,ecs,db_proxy,redis,eks,ecr,waf
7878

7979
echo "Done with generate_provider.sh"

operations/_scripts/generate/generate_vars_terraform.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,27 @@ if [[ $(alpha_only "$AWS_ELB_CREATE") == true ]]; then
132132
aws_elb_additional_tags=$(generate_var aws_elb_additional_tags $AWS_ELB_ADDITIONAL_TAGS)
133133
fi
134134

135+
#-- AWS WAF --#
136+
if [[ $(alpha_only "$AWS_WAF_ENABLE") == true ]]; then
137+
aws_waf_enable=$(generate_var aws_waf_enable $AWS_WAF_ENABLE)
138+
aws_waf_logging_enable=$(generate_var aws_waf_logging_enable $AWS_WAF_LOGGING_ENABLE)
139+
aws_waf_log_retention_days=$(generate_var aws_waf_log_retention_days $AWS_WAF_LOG_RETENTION_DAYS)
140+
aws_waf_additional_tags=$(generate_var aws_waf_additional_tags $AWS_WAF_ADDITIONAL_TAGS)
141+
aws_waf_rule_rate_limit=$(generate_var aws_waf_rule_rate_limit $AWS_WAF_RULE_RATE_LIMIT)
142+
aws_waf_rule_managed_rules=$(generate_var aws_waf_rule_managed_rules $AWS_WAF_RULE_MANAGED_RULES)
143+
aws_waf_rule_managed_bad_inputs=$(generate_var aws_waf_rule_managed_bad_inputs $AWS_WAF_RULE_MANAGED_BAD_INPUTS)
144+
aws_waf_rule_ip_reputation=$(generate_var aws_waf_rule_ip_reputation $AWS_WAF_RULE_IP_REPUTATION)
145+
aws_waf_rule_anonymous_ip=$(generate_var aws_waf_rule_anonymous_ip $AWS_WAF_RULE_ANONYMOUS_IP)
146+
aws_waf_rule_bot_control=$(generate_var aws_waf_rule_bot_control $AWS_WAF_RULE_BOT_CONTROL)
147+
aws_waf_rule_geo_block_countries=$(generate_var aws_waf_rule_geo_block_countries $AWS_WAF_RULE_GEO_BLOCK_COUNTRIES)
148+
aws_waf_rule_geo_allow_only_countries=$(generate_var aws_waf_rule_geo_allow_only_countries $AWS_WAF_RULE_GEO_ALLOW_ONLY_COUNTRIES)
149+
aws_waf_rule_user_arn=$(generate_var aws_waf_rule_user_arn $AWS_WAF_RULE_USER_ARN)
150+
aws_waf_rule_sqli=$(generate_var aws_waf_rule_sqli $AWS_WAF_RULE_SQLI)
151+
aws_waf_rule_linux=$(generate_var aws_waf_rule_linux $AWS_WAF_RULE_LINUX)
152+
aws_waf_rule_unix=$(generate_var aws_waf_rule_unix $AWS_WAF_RULE_UNIX)
153+
aws_waf_rule_admin_protection=$(generate_var aws_waf_rule_admin_protection $AWS_WAF_RULE_ADMIN_PROTECTION)
154+
fi
155+
135156
#-- AWS EFS --#
136157
if [[ $(alpha_only "$AWS_EFS_ENABLE") == true ]]; then
137158
aws_efs_enable=$(generate_var aws_efs_enable $AWS_EFS_ENABLE)
@@ -470,6 +491,25 @@ $aws_elb_access_log_expire
470491
$aws_elb_access_log_bucket_name
471492
$aws_elb_additional_tags
472493
494+
#-- WAF --#
495+
$aws_waf_enable
496+
$aws_waf_logging_enable
497+
$aws_waf_log_retention_days
498+
$aws_waf_additional_tags
499+
$aws_waf_rule_rate_limit
500+
$aws_waf_rule_managed_rules
501+
$aws_waf_rule_managed_bad_inputs
502+
$aws_waf_rule_ip_reputation
503+
$aws_waf_rule_anonymous_ip
504+
$aws_waf_rule_bot_control
505+
$aws_waf_rule_geo_block_countries
506+
$aws_waf_rule_geo_allow_only_countries
507+
$aws_waf_rule_user_arn
508+
$aws_waf_rule_sqli
509+
$aws_waf_rule_linux
510+
$aws_waf_rule_unix
511+
$aws_waf_rule_admin_protection
512+
473513
#-- EFS --#
474514
$aws_efs_enable
475515
$aws_efs_create

operations/deployment/terraform/aws/aws_variables.tf

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,111 @@ variable "aws_elb_additional_tags" {
327327
default = "{}"
328328
}
329329

330+
# AWS LB
331+
332+
# AWS WAF
333+
variable "aws_waf_enable" {
334+
type = bool
335+
description = "Enable WAF for load balancer"
336+
default = false
337+
}
338+
339+
variable "aws_waf_logging_enable" {
340+
type = bool
341+
description = "Enable WAF logging to CloudWatch"
342+
default = false
343+
}
344+
345+
variable "aws_waf_log_retention_days" {
346+
type = number
347+
description = "CloudWatch log retention period for WAF logs"
348+
default = 30
349+
}
350+
351+
variable "aws_waf_additional_tags" {
352+
type = string
353+
description = "A list of strings that will be added to created resources"
354+
default = "{}"
355+
}
356+
357+
variable "aws_waf_rule_rate_limit" {
358+
type = string
359+
description = "Rate limit for WAF rules"
360+
default = "2000"
361+
}
362+
363+
variable "aws_waf_rule_managed_rules" {
364+
type = bool
365+
description = "Enable common managed rule groups to use"
366+
default = false
367+
}
368+
369+
variable "aws_waf_rule_managed_bad_inputs" {
370+
type = bool
371+
description = "Enable managed rule for bad inputs"
372+
default = false
373+
}
374+
375+
variable "aws_waf_rule_ip_reputation" {
376+
type = bool
377+
description = "Enable managed rule for IP reputation"
378+
default = false
379+
}
380+
381+
variable "aws_waf_rule_anonymous_ip" {
382+
type = bool
383+
description = "Enable managed rule for anonymous IP"
384+
default = false
385+
}
386+
387+
variable "aws_waf_rule_bot_control" {
388+
type = bool
389+
description = "Enable managed rule for bot control (costs extra)"
390+
default = false
391+
}
392+
393+
variable "aws_waf_rule_geo_block_countries" {
394+
type = string
395+
description = "Comma separated list of countries to block"
396+
default = ""
397+
}
398+
399+
variable "aws_waf_rule_geo_allow_only_countries" {
400+
type = string
401+
description = "Comma separated list of countries to allow"
402+
default = ""
403+
}
404+
405+
variable "aws_waf_rule_sqli" {
406+
type = bool
407+
description = "Enable managed rule for SQL injection"
408+
default = false
409+
}
410+
411+
variable "aws_waf_rule_linux" {
412+
type = bool
413+
description = "Enable managed rule for Linux"
414+
default = false
415+
}
416+
417+
variable "aws_waf_rule_unix" {
418+
type = bool
419+
description = "Enable managed rule for Unix"
420+
default = false
421+
}
422+
423+
variable "aws_waf_rule_admin_protection" {
424+
type = bool
425+
description = "Enable managed rule for admin protection"
426+
default = false
427+
}
428+
429+
variable "aws_waf_rule_user_arn" {
430+
type = string
431+
description = "ARN of the user rule"
432+
default = ""
433+
}
434+
330435
# AWS EFS
331436

332437
### This variable is hidden for the end user. Is built in deploy.sh based on the next 3 variables.

operations/deployment/terraform/aws/bitovi_main.tf

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ module "aws_route53" {
101101

102102
module "aws_elb" {
103103
source = "../modules/aws/elb"
104-
count = var.aws_ec2_instance_create && var.aws_elb_create ? 1 : 0
104+
count = var.aws_ec2_instance_create && var.aws_elb_create ? 1 : 0
105105
# ELB Values
106106
aws_elb_security_group_name = var.aws_elb_security_group_name
107107
aws_elb_app_port = var.aws_elb_app_port
@@ -530,6 +530,37 @@ module "aws_route53_ecs" {
530530
}
531531
}
532532

533+
module "aws_waf_ecs" {
534+
source = "../modules/aws/waf"
535+
count = var.aws_waf_enable && var.aws_ecs_enable ? 1 : 0
536+
aws_waf_enable = var.aws_waf_enable
537+
aws_waf_logging_enable = var.aws_waf_logging_enable
538+
aws_waf_log_retention_days = var.aws_waf_log_retention_days
539+
aws_resource_identifier = var.aws_resource_identifier
540+
# Rules
541+
aws_waf_rule_rate_limit = var.aws_waf_rule_rate_limit
542+
aws_waf_rule_managed_rules = var.aws_waf_rule_managed_rules
543+
aws_waf_rule_managed_bad_inputs = var.aws_waf_rule_managed_bad_inputs
544+
aws_waf_rule_ip_reputation = var.aws_waf_rule_ip_reputation
545+
aws_waf_rule_anonymous_ip = var.aws_waf_rule_anonymous_ip
546+
aws_waf_rule_bot_control = var.aws_waf_rule_bot_control
547+
aws_waf_rule_geo_block_countries = var.aws_waf_rule_geo_block_countries
548+
aws_waf_rule_geo_allow_only_countries = var.aws_waf_rule_geo_allow_only_countries
549+
aws_waf_rule_user_arn = var.aws_waf_rule_user_arn
550+
aws_waf_rule_sqli = var.aws_waf_rule_sqli
551+
aws_waf_rule_linux = var.aws_waf_rule_linux
552+
aws_waf_rule_unix = var.aws_waf_rule_unix
553+
aws_waf_rule_admin_protection = var.aws_waf_rule_admin_protection
554+
# Incoming
555+
aws_lb_resource_arn = module.aws_ecs[0].load_balancer_arn
556+
# Others
557+
depends_on = [ module.aws_ecs ]
558+
providers = {
559+
aws = aws.waf
560+
}
561+
}
562+
563+
533564
module "aws_ecr" {
534565
source = "../modules/aws/ecr"
535566
count = var.aws_ecr_repo_create ? 1 : 0
@@ -649,6 +680,7 @@ locals {
649680
ecr_tags = merge(local.default_tags,jsondecode(var.aws_ecr_additional_tags))
650681
db_proxy_tags = merge(local.default_tags,jsondecode(var.aws_db_proxy_additional_tags))
651682
redis_tags = merge(local.default_tags,jsondecode(var.aws_redis_additional_tags))
683+
waf_tags = merge(local.default_tags,jsondecode(var.aws_waf_additional_tags))
652684

653685
eks_vpc_tags = {
654686
// This is needed for k8s to use VPC resources

operations/deployment/terraform/modules/aws/ecs/aws_ecs_networking.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ output "load_balancer_zone_id" {
231231
value = aws_alb.ecs_lb.zone_id
232232
}
233233

234+
output "load_balancer_arn" {
235+
value = aws_alb.ecs_lb.arn
236+
}
237+
234238
output "ecs_sg_id" {
235239
value = aws_security_group.ecs_sg.id
236240
}

operations/deployment/terraform/modules/aws/elb/aws_elb.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ resource "aws_s3_bucket_lifecycle_configuration" "lb_access_logs_lifecycle" {
1414
rule {
1515
id = "ExpirationRule"
1616
status = "Enabled"
17+
filter {
18+
prefix = ""
19+
}
1720
expiration {
1821
days = tonumber(var.aws_elb_access_log_expire)
1922
}

0 commit comments

Comments
 (0)