Managing Cloud Armor with Terraform
Learn how to set up and manage Google Cloud Armor security policies using Terraform
In this guide, we’ll explore how to manage Google Cloud Armor using Terraform.
Video Tutorial
Learn more about managing Google Cloud Armor with Terraform in this comprehensive video tutorial:
Prerequisites
- Google Cloud SDK installed and configured
- Terraform installed (version 1.0.0 or later)
- A GCP project with billing enabled
Project Structure
.
├── main.tf # Main Terraform configuration file
├── variables.tf # Variable definitions
├── outputs.tf # Output definitions
├── terraform.tfvars # Variable values
└── modules/
└── armor/
├── main.tf # Cloud Armor specific configurations
├── variables.tf # Module variables
├── policies.tf # Security policy configurations
└── outputs.tf # Module outputs
Provider Configuration
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 4.0"
}
}
}
provider "google" {
project = var.project_id
region = var.region
}
Variables
variable "project_id" {
description = "The ID of the GCP project"
type = string
}
variable "region" {
description = "The region to deploy resources to"
type = string
default = "us-central1"
}
variable "policy_name" {
description = "Name of the Cloud Armor security policy"
type = string
}
Basic Security Policy
resource "google_compute_security_policy" "policy" {
name = var.policy_name
description = "Cloud Armor security policy managed by Terraform"
# Default rule (deny all)
rule {
action = "deny(403)"
priority = "2147483647"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
description = "Default deny rule"
}
# Allow specific IP ranges
rule {
action = "allow"
priority = "1000"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["192.168.1.0/24", "10.0.0.0/8"]
}
}
description = "Allow internal IP ranges"
}
}
Advanced Security Rules
resource "google_compute_security_policy" "advanced_policy" {
name = "${var.policy_name}-advanced"
description = "Advanced Cloud Armor security policy"
# OWASP Top 10 Protection
rule {
action = "deny(403)"
priority = "1000"
match {
expr {
expression = "evaluatePreconfiguredExpr('xss-stable')"
}
}
description = "Prevent XSS attacks"
}
rule {
action = "deny(403)"
priority = "1001"
match {
expr {
expression = "evaluatePreconfiguredExpr('sqli-stable')"
}
}
description = "Prevent SQL injection"
}
# Rate limiting
rule {
action = "rate_based_ban"
priority = "2000"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
description = "Rate limiting rule"
rate_limit_options {
rate_limit_threshold {
count = 100
interval_sec = 60
}
conform_action = "allow"
exceed_action = "deny(429)"
enforce_on_key = "IP"
ban_duration_sec = 300
}
}
# Geolocation-based blocking
rule {
action = "deny(403)"
priority = "3000"
match {
expr {
expression = "origin.region_code == 'RU' || origin.region_code == 'CN'"
}
}
description = "Block specific regions"
}
# Custom request header check
rule {
action = "deny(403)"
priority = "4000"
match {
expr {
expression = "!request.headers['X-Custom-Header'].contains('valid-value')"
}
}
description = "Require custom header"
}
}
WAF Configuration
resource "google_compute_security_policy" "waf_policy" {
name = "${var.policy_name}-waf"
description = "WAF security policy"
# Enable preconfigured rules
rule {
action = "deny(403)"
priority = "1000"
match {
expr {
expression = "evaluatePreconfiguredExpr('cve-canary')"
}
}
description = "Block CVE exploits"
}
# Custom WAF rule
rule {
action = "deny(403)"
priority = "2000"
match {
expr {
expression = "request.headers['user-agent'].contains('bad-bot')"
}
}
description = "Block bad bots"
}
# Adaptive Protection
adaptive_protection_config {
layer_7_ddos_defense_config {
enable = true
rule_visibility = "STANDARD"
}
}
}
Custom Response Configuration
resource "google_compute_security_policy" "custom_response_policy" {
name = "${var.policy_name}-custom-response"
rule {
action = "deny(403)"
priority = "1000"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
description = "Custom denial response"
custom_response_config {
response_code = "403"
response_headers {
header_name = "x-custom-denial"
header_value = "blocked-by-cloud-armor"
}
response_body = base64encode("Access denied by security policy")
}
}
}
Outputs
output "security_policy_id" {
value = google_compute_security_policy.policy.id
description = "The ID of the basic security policy"
}
output "advanced_policy_id" {
value = google_compute_security_policy.advanced_policy.id
description = "The ID of the advanced security policy"
}
output "waf_policy_id" {
value = google_compute_security_policy.waf_policy.id
description = "The ID of the WAF security policy"
}
Best Practices
-
Policy Configuration:
- Layer security rules
- Use appropriate priorities
- Implement rate limiting
- Enable logging
-
Security:
- Enable WAF features
- Monitor traffic patterns
- Regular rule updates
- Implement adaptive protection
-
Performance:
- Optimize rule order
- Monitor latency impact
- Regular testing
- Performance tuning
-
Cost Optimization:
- Monitor policy usage
- Optimize rule count
- Regular cleanup
- Review effectiveness
Common Operations
Creating Resources
terraform init
terraform plan
terraform apply
Testing Security Rules
# Test IP blocking
curl -I http://your-lb-ip
# Test rate limiting
ab -n 1000 -c 10 http://your-lb-ip/
Best Practices and Tips
-
Rule Management:
- Regular updates
- Test changes
- Document rules
- Monitor effectiveness
-
Security:
- Layer defenses
- Regular audits
- Monitor alerts
- Update policies
-
Operations:
- Monitor metrics
- Track attacks
- Regular maintenance
- Update documentation
Conclusion
You’ve learned how to set up and manage Google Cloud Armor using Terraform. This setup provides:
- DDoS protection
- WAF capabilities
- Custom security rules
- Best practices implementation