A step-by-step guide for AWS EC2 provisioning using Terraform: HA, CloudFront, WAF, and SSL Certificate — Part 2

This paper explores two main approaches for integrating AWS WAF with EC2 instances: Application Load Balancers (ALB) and CloudFront. While CloudFront with WAF is cost-effective for static content delivery with basic edge filtering, ALB with WAF offers a more robust solution for dynamic content, advanced traffic management, and comprehensive security. The optimal approach depends on your application’s content mix and prioritization between cost and features. Even a hybrid CloudFront-ALB architecture with WAF

Published Jun 20, 2024
Last Modified Jun 26, 2024
To enhance readability, this handbook is divided into chapters and split into parts. The first, part, “A step-by-step guide for AWS EC2 provisioning using Terraform: HA, ALB, VPC, and Route53 — Part 1”, and the second part “A step-by-step guide for AWS EC2 provisioning using Terraform: HA, CloudFront, WAF, and SSL Certificate — Part 2”, and “A step-by-step guide for AWS EC2 provisioning using Terraform: Cloud Cost Optimization, AWS EC2 Spot Instances — Part 3”, was covered in a separate article to keep the reading time manageable and ensure focused content. The next part or chapter will be published in the next post, upcoming in a few days, “A step-by-step guide for AWS EC2 provisioning using Terraform: VPC peering, VPN, Site-to-site Connection, tunnels ( multi-Cloud ) — Part 9“ and so much more !!

Table of Contents

There are two main approaches to connecting AWS WAF to your EC2 instance

Application Load Balancer (ALB): This is the recommended approach for most scenarios. ALB operates at the application layer (layer 7) and allows for advanced routing and health checks for your EC2 instances. Here’s how it works:
  • You create a web ACL (Web Application Firewall access control list) in AWS WAF with rules to define allowed or blocked traffic.
  • You configure your ALB to associate with the WAF web ACL.
  • Traffic destined for your EC2 instances first passes through the ALB, where the WAF rules are applied.
  • The ALB-only forwards allowed traffic to your healthy EC2 instances.
AWS CloudFront: CloudFront is a content delivery network (CDN) that sits in front of your origin server (in this case, your EC2 instance). CloudFront can integrate with AWS WAF to provide some basic web filtering at the edge locations. However, compared to ALB, CloudFront offers less granular control over traffic management and health checks. Here’s how it works:
  • You create a web ACL in AWS WAF with rules to define allowed or blocked traffic.
  • You configure your CloudFront distribution to associate with the WAF web ACL.
  • Traffic reaches CloudFront edge locations where WAF rules are applied.
  • CloudFront only forwards allowed traffic to your EC2 instance.
AWS WAF
Choosing the Right Approach:
  • Use ALB for most scenarios: For robust application layer protection with advanced routing and health checks, choose an ALB with WAF. This is the most secure and scalable approach.
  • Consider CloudFront with WAF for specific situations: If you primarily need basic web filtering at the edge locations for content delivery and cost optimization might be a priority, CloudFront with WAF can be a suitable option. However, be aware of its limitations compared to an ALB.

CloudFront, WAF, and SSL Configuration using Terraform

To add CloudFront, WAF, and SSL Certificate, you’ll need to add additional resources:
# CloudFront Distribution
resource "aws_cloudfront_distribution" "cdn" {
enabled = true
origin {
domain_name = aws_instance.prodxcloud-lab-1.public_ip
origin_id = "studio.prodxcloud.io"
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "https-only"
origin_ssl_protocols = ["TLSv1.2"]
}
}
# SSL Certificate for CloudFront
default_cache_behavior {
viewer_protocol_policy = "redirect-to-https"
allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
cached_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
target_origin_id = "Custom-origin"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
# WAF Configuration (AWS WAFv2)
web_acl_id = aws_wafv2_web_acl.example.id
# SSL Certificate
viewer_certificate {
acm_certificate_arn = "arn:aws:acm:us-east-1:059978233428:certificate/9262ee7e-82ab-4ce0-8789-6ebb0274a30f"
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.1_2016"
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
}
# AWS WAFv2 Web ACL
resource "aws_wafv2_web_acl" "example" {

name = "example-web-acl"
scope = "REGIONAL"
visibility_config {
cloudwatch_metrics_enabled = false
metric_name = "friendly-rule-metric-name"
sampled_requests_enabled = false
}
default_action {
allow {}
}
}

Steps to Deploy EC2 using terraform

  1. Initialize Terraform
terraform init
2. Plan the Deployment
terraform plan
3. Apply the Configuration
terraform apply
First, CloudFront Distribution: Configures CloudFront CDN with an SSL certificate and WAF integration.
AWS EC2 Instance running behind Cloudfront with Custom ID
Second, WAF Configuration: Defines a WAF web ACL with AWS Managed Rules.
Manual Operation (Optional)
Step 1Step 2: Add AWS Resources
Nevertheless, you can simplify this work by simply using terraform as follows:
# waf.tf
provider "aws" {
region = "us-east-1" # AWS WAF must be in us-east-1 for CloudFront
}
# Create an AWS WAFv2 Web ACL
resource "aws_wafv2_web_acl" "example" {
name = "example-web-acl"
description = "Example WAF Web ACL"
scope = "CLOUDFRONT" # Scope must be CLOUDFRONT for CloudFront distributions
default_action {
allow {}
}
rule {
name = "example-block-rule"
priority = 1
action {
block {}
}
statement {
byte_match_statement {
search_string = "blocked-string"
field_to_match {
single_header {
name = "User-Agent"
}
}
text_transformations {
priority = 0
type = "NONE"
}
positional_constraint = "CONTAINS"
}
}
visibility_config {
sampled_requests_enabled = true
cloudwatch_metrics_enabled = true
metric_name = "example-block-rule"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "example-web-acl"
sampled_requests_enabled = true
}
}
# Create an AWS CloudFront distribution
resource "aws_cloudfront_distribution" "example" {
origin {
domain_name = "your-origin-domain.com"
origin_id = "custom-origin-id"
}
enabled = true
is_ipv6_enabled = true
default_root_object = "index.html"
default_cache_behavior {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "custom-origin-id"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
Explanation:
  • This code defines a WAF Web ACL named "my-web-acl" with a default action to block requests (can be changed to allow).
  • It then creates a rule named "BlockXssAttack" with a priority of 10 (lower numbers have higher priority).
  • The rule statement uses a managed rule group statement from AWS named "AWSManagedRulesCommonRuleSet". This pre-configured rule set helps protect against common web vulnerabilities like XSS (Cross-Site Scripting).
  • Finally, a visibility configuration enables CloudWatch metrics collection for the rule, allowing you to monitor its effectiveness.
Update: Once you are done with this tutorial, you might to check up a follow-up tutorial on the next part, A step-by-step guide for AWS EC2 provisioning using Terraform: Cloud Cost Optimization, AWS EC2 Spot Instances — Part 3

Conclusion

In conclusion, selecting the right approach to connect AWS WAF to your EC2 instances depends on your application’s specific needs. CloudFront with WAF excels at delivering cached content efficiently and offers basic web filtering at the edge, making it cost-effective for static content-heavy applications. However, for applications with dynamic content or requiring advanced traffic management, an ALB with WAF provides a more comprehensive solution with robust security, scalability, and control. Consider a hybrid CloudFront-ALB architecture with WAF for complex scenarios with a mix of content types and cost optimization as a priority. By carefully evaluating your application’s characteristics, you can choose the most secure, performant, and cost-effective approach for connecting WAF to your EC2 instances.
To enhance readability, this handbook is divided into chapters and split into parts. The first, part, “A step-by-step guide for AWS EC2 provisioning using Terraform: HA, ALB, VPC, and Route53 — Part 1”, and the second part “A step-by-step guide for AWS EC2 provisioning using Terraform: HA, CloudFront, WAF, and SSL Certificate — Part 2”, and “A step-by-step guide for AWS EC2 provisioning using Terraform: Cloud Cost Optimization, AWS EC2 Spot Instances — Part 3”, was covered in a separate article to keep the reading time manageable and ensure focused content. The next part or chapter will be published in the next post, upcoming in a few days, “A step-by-step guide for AWS EC2 provisioning using Terraform: VPC peering, VPN, Site-to-site Connection, tunnels ( multi-Cloud ) — Part 9“ and so much more !!
Thank you for Reading !! 🙌🏻, don’t forget to subscribe and give it a CLAP 👏, and if you found this article useful contact me or feel free to sponsor me to produce more public content. see me in the next article.🤘
I am Joel Wembo, AWS certified cloud Solutions architect, Back-end developer, and AWS Community Builder, I‘m based in the Philippines 🇵🇭; and currently working at prodxcloud as a DevOps & Cloud Architect. I bring a powerful combination of expertise in cloud architecture, DevOps practices, and a deep understanding of high availability (HA) principles. I leverage my knowledge to create robust, scalable cloud applications using open-source tools for efficient enterprise deployments.
I’m looking to collaborate on AWS CDK, AWS SAM, DevOps CI/CD, Serverless Framework, CloudFormation, Terraform, Kubernetes, TypeScript, GitHub Actions, PostgreSQL, and Django.”
For more information about the author ( Joel O. Wembo ) visit:
Links:
🚀 A step-by-step guide for AWS EC2 provisioning using Terraform: How to set up SSM ( AWS Systems Manager ) for EC2? — Part 14
and Much More …
 

Comments