diff --git a/README.md b/README.md
index 2c3cb49f..9f16f045 100644
--- a/README.md
+++ b/README.md
@@ -45,6 +45,59 @@ jobs:
additional_tags: '{\"key\":\"value\",\"key2\":\"value2\"}'
```
+### ALB with WAF example
+```yaml
+name: Deploy with Application Load Balancer and WAF
+on:
+ push:
+ branches: [ main ]
+
+jobs:
+ EC2-Deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - id: deploy
+ uses: bitovi/github-actions-deploy-commons@main
+ with:
+ aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ aws_default_region: us-east-1
+ env_ghs: ${{ secrets.DOT_ENV }}
+ # Load Balancer Configuration
+ aws_elb_create: true
+ aws_lb_type: alb # Use Application Load Balancer instead of Classic ELB
+ aws_alb_enable_waf: true # Enable AWS WAF v2 protection
+ aws_alb_subnets: subnet-12345,subnet-67890 # Specify subnets for ALB
+ # VPC Configuration (required for ALB)
+ aws_vpc_create: true
+ aws_vpc_public_subnets: 10.0.1.0/24,10.0.2.0/24
+ aws_vpc_availability_zones: us-east-1a,us-east-1b
+```
+
+### ALB with default VPC example
+```yaml
+name: Deploy with ALB using default VPC (single-AZ)
+on:
+ push:
+ branches: [ main ]
+
+jobs:
+ EC2-Deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - id: deploy
+ uses: bitovi/github-actions-deploy-commons@main
+ with:
+ aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ aws_default_region: us-east-1
+ env_ghs: ${{ secrets.DOT_ENV }}
+ # Simple ALB setup using default VPC
+ aws_elb_create: true
+ aws_lb_type: alb # Use ALB instead of Classic ELB
+ # Note: aws_alb_subnets not specified = single-AZ deployment
+```
+
## Customizing
### Inputs
@@ -198,6 +251,7 @@ The following inputs can be used as `step.with` keys
| Name | Type | Description |
|------------------|---------|------------------------------------|
| `aws_elb_create` | Boolean | Toggles the creation of a load balancer and map ports to the EC2 instance. Defaults to `false`.|
+| `aws_lb_type` | String | Type of load balancer to create. Options: `elb` (Classic Load Balancer) or `alb` (Application Load Balancer). Defaults to `elb`. ALB supports WAF integration and Layer 7 routing. |
| `aws_elb_security_group_name` | String | The name of the ELB security group. Defaults to `SG for ${aws_resource_identifier} - ELB`. |
| `aws_elb_app_port` | String | Port in the EC2 instance to be redirected to. Default is `3000`. Accepts comma separated values like `3000,3001`. |
| `aws_elb_app_protocol` | String | Protocol to enable. Could be HTTP, HTTPS, TCP or SSL. Defaults to `TCP`. If length doesn't match, will use `TCP` for all.|
@@ -207,6 +261,11 @@ The following inputs can be used as `step.with` keys
| `aws_elb_access_log_bucket_name` | String | S3 bucket name to store the ELB access logs. Defaults to `${aws_resource_identifier}-logs` (or `-lg `depending of length). **Bucket will be deleted if stack is destroyed.** |
| `aws_elb_access_log_expire` | String | Delete the access logs after this amount of days. Defaults to `90`. Set to `0` in order to disable this policy. |
| `aws_elb_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 elb provisioned resources.|
+| **ALB-specific inputs (when aws_lb_type = "alb")** | | |
+| `aws_alb_enable_waf` | Boolean | Enable AWS WAF v2 integration for the ALB. Only works with ALB (`aws_lb_type = "alb"`). Defaults to `false`. |
+| `aws_alb_subnets` | String | Comma-separated list of subnet IDs for ALB placement. If not provided, will use the same subnet as the EC2 instance (single-AZ deployment). For production, specify multiple subnets across different AZs for high availability. |
+
+**Note**: When using ALB with default VPC (no explicit VPC creation), the ALB will be placed in the same subnet as the EC2 instance. While this works functionally, it results in a single Availability Zone deployment which may not be suitable for production workloads requiring high availability.
diff --git a/action.yaml b/action.yaml
index 0d0cf2bd..0dfc2385 100644
--- a/action.yaml
+++ b/action.yaml
@@ -279,6 +279,17 @@ inputs:
aws_elb_additional_tags:
description: 'A JSON object of additional tags that will be included on created resources. Example: `{"key1": "value1", "key2": "value2"}`'
required: false
+
+ # AWS Load Balancer Type
+ aws_lb_type:
+ description: 'Load balancer type: "elb" or "alb". Defaults to "elb"'
+ required: false
+ aws_alb_enable_waf:
+ description: 'Enable AWS WAF v2 for ALB (only applicable when aws_lb_type is "alb")'
+ required: false
+ aws_alb_subnets:
+ description: 'Comma-separated list of subnet IDs for ALB. If empty, will use single subnet from VPC configuration (only applicable when aws_lb_type is "alb")'
+ required: false
# AWS EFS
aws_efs_create:
@@ -1200,6 +1211,11 @@ runs:
AWS_ELB_ACCESS_LOG_EXPIRE: ${{ inputs.aws_elb_access_log_expire }}
AWS_ELB_ADDITIONAL_TAGS: ${{ inputs.aws_elb_additional_tags }}
+ # AWS Load Balancer Type
+ AWS_LB_TYPE: ${{ inputs.aws_lb_type }}
+ AWS_ALB_ENABLE_WAF: ${{ inputs.aws_alb_enable_waf }}
+ AWS_ALB_SUBNETS: ${{ inputs.aws_alb_subnets }}
+
# AWS EFS
AWS_EFS_CREATE: ${{ inputs.aws_efs_create }}
AWS_EFS_FS_ID: ${{ inputs.aws_efs_fs_id }}
diff --git a/operations/_scripts/generate/generate_vars_terraform.sh b/operations/_scripts/generate/generate_vars_terraform.sh
index 14e5b458..941c7b3f 100644
--- a/operations/_scripts/generate/generate_vars_terraform.sh
+++ b/operations/_scripts/generate/generate_vars_terraform.sh
@@ -130,6 +130,10 @@ if [[ $(alpha_only "$AWS_ELB_CREATE") == true ]]; then
aws_elb_access_log_bucket_name=$(generate_var aws_elb_access_log_bucket_name $AWS_ELB_ACCESS_LOG_BUCKET_NAME)
aws_elb_access_log_expire=$(generate_var aws_elb_access_log_expire $AWS_ELB_ACCESS_LOG_EXPIRE)
aws_elb_additional_tags=$(generate_var aws_elb_additional_tags $AWS_ELB_ADDITIONAL_TAGS)
+ # ALB/LB wrapper variables
+ aws_lb_type=$(generate_var aws_lb_type $AWS_LB_TYPE)
+ aws_alb_enable_waf=$(generate_var aws_alb_enable_waf $AWS_ALB_ENABLE_WAF)
+ aws_alb_subnets=$(generate_var aws_alb_subnets $AWS_ALB_SUBNETS)
fi
#-- AWS EFS --#
diff --git a/operations/deployment/terraform/aws/aws_variables.tf b/operations/deployment/terraform/aws/aws_variables.tf
index cba19a2e..4fd8bbf4 100644
--- a/operations/deployment/terraform/aws/aws_variables.tf
+++ b/operations/deployment/terraform/aws/aws_variables.tf
@@ -327,6 +327,30 @@ variable "aws_elb_additional_tags" {
default = "{}"
}
+variable "aws_lb_type" {
+ type = string
+ description = "Load balancer type: 'elb' or 'alb'"
+ default = "elb"
+}
+
+variable "aws_alb_enable_waf" {
+ type = bool
+ description = "Enable AWS WAF v2 for ALB"
+ default = false
+}
+
+variable "aws_waf_rules" {
+ type = list(string)
+ description = "WAF rule types to enable"
+ default = ["AWSManagedRulesCommonRuleSet"]
+}
+
+variable "aws_alb_subnets" {
+ type = string
+ description = "Comma-separated list of subnet IDs for ALB. If empty, will use single subnet from VPC configuration."
+ default = ""
+}
+
# AWS EFS
### This variable is hidden for the end user. Is built in deploy.sh based on the next 3 variables.
diff --git a/operations/deployment/terraform/aws/bitovi_main.tf b/operations/deployment/terraform/aws/bitovi_main.tf
index 7597b904..58021150 100644
--- a/operations/deployment/terraform/aws/bitovi_main.tf
+++ b/operations/deployment/terraform/aws/bitovi_main.tf
@@ -100,8 +100,10 @@ module "aws_route53" {
}
module "aws_elb" {
- source = "../modules/aws/elb"
+ source = "../modules/aws/aws_lb"
count = var.aws_ec2_instance_create && var.aws_elb_create ? 1 : 0
+ # Load Balancer Type
+ aws_lb_type = var.aws_lb_type
# ELB Values
aws_elb_security_group_name = var.aws_elb_security_group_name
aws_elb_app_port = var.aws_elb_app_port
@@ -119,6 +121,9 @@ module "aws_elb" {
aws_elb_target_sg_id = module.ec2[0].aws_security_group_ec2_sg_id
# Certs
aws_certificates_selected_arn = var.aws_r53_enable_cert && var.aws_r53_domain_name != "" ? module.aws_certificates[0].selected_arn : ""
+ # ALB specific variables
+ aws_alb_enable_waf = var.aws_alb_enable_waf
+ aws_alb_subnets = var.aws_alb_subnets != "" ? [for n in split(",", var.aws_alb_subnets) : n] : []
# Others
aws_resource_identifier = var.aws_resource_identifier
aws_resource_identifier_supershort = var.aws_resource_identifier_supershort
diff --git a/operations/deployment/terraform/modules/aws/alb/aws_alb.tf b/operations/deployment/terraform/modules/aws/alb/aws_alb.tf
new file mode 100644
index 00000000..853bce57
--- /dev/null
+++ b/operations/deployment/terraform/modules/aws/alb/aws_alb.tf
@@ -0,0 +1,202 @@
+data "aws_elb_service_account" "main" {}
+
+# S3 bucket for ALB access logs
+resource "aws_s3_bucket" "lb_access_logs" {
+ bucket = var.aws_elb_access_log_bucket_name
+ force_destroy = true
+ tags = {
+ Name = var.aws_elb_access_log_bucket_name
+ }
+}
+
+resource "aws_s3_bucket_lifecycle_configuration" "lb_access_logs_lifecycle" {
+ count = tonumber(var.aws_elb_access_log_expire) > 0 ? 1 : 0
+ bucket = aws_s3_bucket.lb_access_logs.id
+ rule {
+ id = "ExpirationRule"
+ status = "Enabled"
+ filter {
+ prefix = ""
+ }
+ expiration {
+ days = tonumber(var.aws_elb_access_log_expire)
+ }
+ }
+}
+
+resource "aws_s3_bucket_policy" "allow_access_from_elb_account" {
+ bucket = aws_s3_bucket.lb_access_logs.id
+ policy = < 0 ? var.aws_alb_subnets : [var.aws_vpc_subnet_selected]
+}
+
+# Outputs
+output "aws_elb_dns_name" {
+ value = aws_lb.alb.dns_name
+}
+
+output "aws_elb_zone_id" {
+ value = aws_lb.alb.zone_id
+}
+
+output "alb_arn" {
+ value = aws_lb.alb.arn
+}
+
+output "alb_target_group_arns" {
+ value = aws_lb_target_group.alb_targets[*].arn
+}
diff --git a/operations/deployment/terraform/modules/aws/alb/aws_alb_providers.tf b/operations/deployment/terraform/modules/aws/alb/aws_alb_providers.tf
new file mode 100644
index 00000000..1ac87da5
--- /dev/null
+++ b/operations/deployment/terraform/modules/aws/alb/aws_alb_providers.tf
@@ -0,0 +1,8 @@
+terraform {
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.0"
+ }
+ }
+}
diff --git a/operations/deployment/terraform/modules/aws/alb/aws_alb_vars.tf b/operations/deployment/terraform/modules/aws/alb/aws_alb_vars.tf
new file mode 100644
index 00000000..dc298bbc
--- /dev/null
+++ b/operations/deployment/terraform/modules/aws/alb/aws_alb_vars.tf
@@ -0,0 +1,32 @@
+# ALB compatible variables (mapped from ELB naming for consistency)
+variable "aws_elb_security_group_name" {}
+variable "aws_elb_app_port" {}
+variable "aws_elb_app_protocol" {}
+variable "aws_elb_listen_port" {}
+variable "aws_elb_listen_protocol" {}
+variable "aws_elb_healthcheck" {}
+variable "aws_elb_access_log_bucket_name" {}
+variable "aws_elb_access_log_expire" {}
+
+variable "aws_instance_server_az" {}
+variable "aws_vpc_selected_id" {}
+variable "aws_vpc_subnet_selected" {}
+variable "aws_instance_server_id" {}
+variable "aws_certificates_selected_arn" {}
+variable "aws_elb_target_sg_id" {}
+
+variable "aws_resource_identifier" {}
+variable "aws_resource_identifier_supershort" {}
+
+# ALB specific variables
+variable "aws_alb_enable_waf" {
+ type = bool
+ description = "Enable AWS WAF v2 for ALB"
+ default = false
+}
+
+variable "aws_alb_subnets" {
+ type = list(string)
+ description = "List of subnet IDs for ALB (will default to using single subnet if not provided)"
+ default = []
+}
diff --git a/operations/deployment/terraform/modules/aws/aws_lb/README.md b/operations/deployment/terraform/modules/aws/aws_lb/README.md
new file mode 100644
index 00000000..236f996f
--- /dev/null
+++ b/operations/deployment/terraform/modules/aws/aws_lb/README.md
@@ -0,0 +1,92 @@
+# AWS Load Balancer Wrapper Module
+
+This module provides a unified interface for deploying either Classic ELB or Application Load Balancer (ALB) based on the `aws_lb_type` variable.
+
+## Usage
+
+```terraform
+module "aws_lb" {
+ source = "./modules/aws/aws_lb"
+
+ # Choose load balancer type
+ aws_lb_type = "alb" # or "elb"
+
+ # Common configuration for both ELB and ALB
+ aws_elb_security_group_name = "my-lb-sg"
+ aws_elb_app_port = "3000"
+ aws_elb_listen_port = "80,443"
+ aws_elb_healthcheck = "HTTP:3000/"
+ aws_elb_access_log_bucket_name = "my-lb-logs-bucket"
+
+ # ALB-specific options (ignored when using ELB)
+ aws_alb_enable_waf = true
+ aws_alb_subnets = ["subnet-123", "subnet-456"]
+
+ # Required variables
+ aws_vpc_selected_id = "vpc-123"
+ aws_instance_server_id = "i-123"
+ # ... other required variables
+}
+```
+
+## Load Balancer Types
+
+### Classic ELB (`aws_lb_type = "elb"`)
+- Layer 4 load balancer
+- Supports TCP, HTTP, HTTPS, SSL protocols
+- Single availability zone deployment (using `aws_vpc_subnet_selected`)
+- Legacy option but still supported
+
+### Application Load Balancer (`aws_lb_type = "alb"`)
+- Layer 7 load balancer
+- HTTP/HTTPS only
+- Multi-AZ deployment (using `aws_alb_subnets` or falls back to single subnet)
+- Advanced routing capabilities
+- WAF support (when `aws_alb_enable_waf = true`)
+- Modern option with more features
+
+## Variables
+
+### Common Variables (used by both ELB and ALB)
+- `aws_lb_type` - Type of load balancer: "elb" or "alb" (default: "elb")
+- `aws_elb_security_group_name` - Security group name
+- `aws_elb_app_port` - Application port(s) (comma-separated)
+- `aws_elb_listen_port` - Listener port(s) (comma-separated)
+- `aws_elb_healthcheck` - Health check configuration
+- `aws_elb_access_log_bucket_name` - S3 bucket for access logs
+- And other standard ELB variables...
+
+### ALB-Specific Variables
+- `aws_alb_enable_waf` - Enable AWS WAF v2 (boolean, default: false)
+- `aws_alb_subnets` - List of subnet IDs for multi-AZ ALB deployment
+
+## Outputs
+
+### Common Outputs (available for both types)
+- `aws_elb_dns_name` - DNS name of the load balancer
+- `aws_elb_zone_id` - Route53 zone ID of the load balancer
+- `lb_type` - Type of load balancer deployed
+
+### ALB-Specific Outputs
+- `alb_arn` - ARN of the ALB (empty if using ELB)
+- `alb_target_group_arns` - ARNs of ALB target groups (empty if using ELB)
+
+## Migration from ELB to ALB
+
+To migrate from ELB to ALB, simply change:
+```terraform
+aws_lb_type = "alb"
+```
+
+And optionally add ALB-specific configuration:
+```terraform
+aws_alb_enable_waf = true
+aws_alb_subnets = ["subnet-1", "subnet-2"] # For multi-AZ
+```
+
+## Notes
+
+- When using ALB, ensure you have at least one public subnet
+- ALB requires multiple subnets for high availability, but will fall back to single subnet if `aws_alb_subnets` is empty
+- WAF is only available with ALB, not Classic ELB
+- The module maintains backward compatibility with existing ELB configurations
diff --git a/operations/deployment/terraform/modules/aws/aws_lb/aws_lb.tf b/operations/deployment/terraform/modules/aws/aws_lb/aws_lb.tf
new file mode 100644
index 00000000..6b48d3bc
--- /dev/null
+++ b/operations/deployment/terraform/modules/aws/aws_lb/aws_lb.tf
@@ -0,0 +1,77 @@
+# ELB Module (Classic Load Balancer)
+module "elb" {
+ source = "../elb"
+ count = var.aws_lb_type == "elb" ? 1 : 0
+
+ # Pass all ELB variables
+ aws_elb_security_group_name = var.aws_elb_security_group_name
+ aws_elb_app_port = var.aws_elb_app_port
+ aws_elb_app_protocol = var.aws_elb_app_protocol
+ aws_elb_listen_port = var.aws_elb_listen_port
+ aws_elb_listen_protocol = var.aws_elb_listen_protocol
+ aws_elb_healthcheck = var.aws_elb_healthcheck
+ aws_elb_access_log_bucket_name = var.aws_elb_access_log_bucket_name
+ aws_elb_access_log_expire = var.aws_elb_access_log_expire
+ aws_instance_server_az = var.aws_instance_server_az
+ aws_vpc_selected_id = var.aws_vpc_selected_id
+ aws_vpc_subnet_selected = var.aws_vpc_subnet_selected
+ aws_instance_server_id = var.aws_instance_server_id
+ aws_certificates_selected_arn = var.aws_certificates_selected_arn
+ aws_elb_target_sg_id = var.aws_elb_target_sg_id
+ aws_resource_identifier = var.aws_resource_identifier
+ aws_resource_identifier_supershort = var.aws_resource_identifier_supershort
+}
+
+# ALB Module (Application Load Balancer)
+module "alb" {
+ source = "../alb"
+ count = var.aws_lb_type == "alb" ? 1 : 0
+
+ # Pass all ALB variables (using ELB variable names for consistency)
+ aws_elb_security_group_name = var.aws_elb_security_group_name
+ aws_elb_app_port = var.aws_elb_app_port
+ aws_elb_app_protocol = var.aws_elb_app_protocol
+ aws_elb_listen_port = var.aws_elb_listen_port
+ aws_elb_listen_protocol = var.aws_elb_listen_protocol
+ aws_elb_healthcheck = var.aws_elb_healthcheck
+ aws_elb_access_log_bucket_name = var.aws_elb_access_log_bucket_name
+ aws_elb_access_log_expire = var.aws_elb_access_log_expire
+ aws_instance_server_az = var.aws_instance_server_az
+ aws_vpc_selected_id = var.aws_vpc_selected_id
+ aws_vpc_subnet_selected = var.aws_vpc_subnet_selected
+ aws_instance_server_id = var.aws_instance_server_id
+ aws_certificates_selected_arn = var.aws_certificates_selected_arn
+ aws_elb_target_sg_id = var.aws_elb_target_sg_id
+ aws_resource_identifier = var.aws_resource_identifier
+ aws_resource_identifier_supershort = var.aws_resource_identifier_supershort
+ # ALB specific variables
+ aws_alb_enable_waf = var.aws_alb_enable_waf
+ aws_alb_subnets = var.aws_alb_subnets
+}
+
+# Unified outputs that work regardless of LB type
+output "aws_elb_dns_name" {
+ description = "DNS name of the load balancer"
+ value = var.aws_lb_type == "elb" ? try(module.elb[0].aws_elb_dns_name, "") : try(module.alb[0].aws_elb_dns_name, "")
+}
+
+output "aws_elb_zone_id" {
+ description = "Zone ID of the load balancer"
+ value = var.aws_lb_type == "elb" ? try(module.elb[0].aws_elb_zone_id, "") : try(module.alb[0].aws_elb_zone_id, "")
+}
+
+# Additional outputs for ALB-specific features
+output "alb_arn" {
+ description = "ARN of the ALB (empty if using ELB)"
+ value = var.aws_lb_type == "alb" ? try(module.alb[0].alb_arn, "") : ""
+}
+
+output "alb_target_group_arns" {
+ description = "ARNs of ALB target groups (empty if using ELB)"
+ value = var.aws_lb_type == "alb" ? try(module.alb[0].alb_target_group_arns, []) : []
+}
+
+output "lb_type" {
+ description = "Type of load balancer deployed"
+ value = var.aws_lb_type
+}
diff --git a/operations/deployment/terraform/modules/aws/aws_lb/aws_lb_providers.tf b/operations/deployment/terraform/modules/aws/aws_lb/aws_lb_providers.tf
new file mode 100644
index 00000000..1ac87da5
--- /dev/null
+++ b/operations/deployment/terraform/modules/aws/aws_lb/aws_lb_providers.tf
@@ -0,0 +1,8 @@
+terraform {
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.0"
+ }
+ }
+}
diff --git a/operations/deployment/terraform/modules/aws/aws_lb/aws_lb_vars.tf b/operations/deployment/terraform/modules/aws/aws_lb/aws_lb_vars.tf
new file mode 100644
index 00000000..ee6b88a1
--- /dev/null
+++ b/operations/deployment/terraform/modules/aws/aws_lb/aws_lb_vars.tf
@@ -0,0 +1,39 @@
+# Load balancer type
+variable "aws_lb_type" {
+ type = string
+ description = "Load balancer type: 'elb' or 'alb'"
+ default = "elb"
+}
+
+# Common variables for both ELB and ALB
+variable "aws_elb_security_group_name" {}
+variable "aws_elb_app_port" {}
+variable "aws_elb_app_protocol" {}
+variable "aws_elb_listen_port" {}
+variable "aws_elb_listen_protocol" {}
+variable "aws_elb_healthcheck" {}
+variable "aws_elb_access_log_bucket_name" {}
+variable "aws_elb_access_log_expire" {}
+
+variable "aws_instance_server_az" {}
+variable "aws_vpc_selected_id" {}
+variable "aws_vpc_subnet_selected" {}
+variable "aws_instance_server_id" {}
+variable "aws_certificates_selected_arn" {}
+variable "aws_elb_target_sg_id" {}
+
+variable "aws_resource_identifier" {}
+variable "aws_resource_identifier_supershort" {}
+
+# ALB specific variables
+variable "aws_alb_enable_waf" {
+ type = bool
+ description = "Enable AWS WAF v2 for ALB"
+ default = false
+}
+
+variable "aws_alb_subnets" {
+ type = list(string)
+ description = "List of subnet IDs for ALB (will default to using single subnet if not provided)"
+ default = []
+}
diff --git a/operations/deployment/terraform/modules/aws/elb/aws_elb.tf b/operations/deployment/terraform/modules/aws/elb/aws_elb.tf
index 621fb7b6..19e18eea 100644
--- a/operations/deployment/terraform/modules/aws/elb/aws_elb.tf
+++ b/operations/deployment/terraform/modules/aws/elb/aws_elb.tf
@@ -14,6 +14,9 @@ resource "aws_s3_bucket_lifecycle_configuration" "lb_access_logs_lifecycle" {
rule {
id = "ExpirationRule"
status = "Enabled"
+ filter {
+ prefix = ""
+ }
expiration {
days = tonumber(var.aws_elb_access_log_expire)
}