How to Create Cloud Armor on GCP Using Terraform
👨💻 Introduction
In this article explains how to configure Google Cloud Armor security policies using Terraform on Google Cloud Platform (GCP).
Prerequisites
Google Cloud Platform (GCP) Account: Make sure you have a valid GCP account.
Install Terraform: If Terraform is not already installed, refer to the Terraform Installation Guide.
Basic Terraform Knowledge: Familiarize yourself with basic Terraform commands and concepts. The Terraform Getting Started Guide can be a helpful resource.
🎯 Setup
Step 1: Create provider.tf
Define the GCP Provider and the Terraform version required.
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "5.7.0"
}
}
}
provider "google" {
project = "your-project-id"
region = "asia-east1"
}
Step 2: Create main.tf
In this file, define the Google Cloud Armor security policy resources.
Security Policy
resource "google_compute_security_policy" "default" {
name = "my-security-policy"
rule {
action = "allow"
priority = 1000
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["0.0.0.0/0"]
}
}
}
}
Parameter Introduction
name: The name of the security policy.
action: The action to take (e.g., ‘allow’ or ‘deny’).
priority: The priority of the rule.
versioned_expr: The version of the expression.
src_ip_ranges: Source IP ranges to match.
Step 3: Initialize Terraform
terraform init
Step 4: Execute Dry Run
terraform plan
Step 5: Deploy
terraform apply
Resource Deletion
To clean up resources after deployment:
terraform destroy
🛠️ Modularizing Terraform Configuration for Google Cloud Armor
Understanding Dynamic Blocks and Iterator
Before diving into the modularization of the Terraform configuration, let’s understand two advanced features of Terraform: dynamic blocks and iterator.
Dynamic Blocks: In Terraform, dynamic blocks are used to dynamically construct repeatable nested blocks within a resource based on a complex variable (like a list or map). This feature is particularly useful when you need to create multiple similar configurations within a resource but the exact number or composition of these blocks may vary.
Iterator: An iterator is an optional argument used within a dynamic block that allows you to customize the naming of the temporary variable for each item in the complex variable. By default, Terraform uses each as the iterator, but you can specify a different name to improve clarity or avoid conflicts with other variables.
1. Refactoring main.tf
for Modularity
When refactoring main.tf
for the Google Cloud Armor module, we’ll use dynamic
blocks and an iterator
to efficiently create security rules from a list of objects.
Google Cloud Armor Module:
resource "google_compute_security_policy" "main" {
name = var.name
dynamic "rule" {
for_each = var.rules_src_ip_ranges
iterator = allow
content {
action = allow.value.action
priority = allow.value.priority
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = allow.value.ranges
}
}
description = allow.value.description
}
}
dynamic "rule" {
for_each = var.rules_expression
iterator = deny
content {
action = deny.value.action
priority = deny.value.priority
match {
expr {
expression = deny.value.expression
}
}
description = deny.value.description
}
}
}
In this example:
We use two
dynamic
blocks to create different types of security rules: one for source IP range-based rules and another for expression-based rules.Each
dynamic
block iterates over a list of objects (eitherrules_src_ip_ranges
orrules_expression
), creating a new rule for each object in the list.The
iterator
(namedallow
for the first block anddeny
for the second) refers to each item in the list during each iteration.
2. Defining Variables in variables.tf
Define the necessary variables in a variables.tf
file. These variables will be used to dynamically generate the security rules in the module.
Variable Definitions:
variable "security_policy_name" {
description = "The name for the security policy"
type = string
}
variable "rules_src_ip_ranges" {
description = "A list of security rules src ip ranges to be applied"
type = list(object({
action = string
priority = number
ranges = list(string)
description = string
}))
}
variable "rules_expression" {
description = "A list of security rules expression to be applied"
type = list(object({
action = string
priority = number
expression = string
description = string
}))
}
3. Creating the Google Cloud Armor Module
Create a directory modules/cloud_armor
and add a cloud_armor.tf
.
Module Definition (
cloud_armor.tf
):
module "google_cloud_armor" {
source = "./modules/cloud_armor"
name = "my-security-policy"
rules_src_ip_ranges = [{
action = "allow"
priority = 1
ranges = ["0.0.0.0/0"]
description = "allow all"
}
]
rules_expression = [{
action = "deny(403)"
priority = 2
expression = "request.headers['x-forwarded-for'].contains('127.0.0.1')"
description = "deny 127.0.0.1"
}
]
}
Here’s an example of how you might structure your folders and files for this project:
terraform-google-cloud-armor/
│
├── main.tf # Main Terraform configuration file
├── provider.tf # Provider configuration
│
├── modules/ # Directory containing all modular code
│ └── cloud_armor/ # Google Cloud Armor module
│ ├── main.tf # Main file for the Cloud Armor module
│ ├── variables.tf # Variables specific to the Cloud Armor module
│
└── terraform.tfvars # (Optional) File to define values for your variables
4. Applying the Modular Configuration
Run the following Terraform commands in your project’s root directory:
Initialize Terraform:
terraform init
Execute a Dry Run:
terraform plan
Apply the Configuration:
terraform apply
This modular approach to configuring Google Cloud Armor using Terraform offers a scalable and manageable way to handle security policies.
0 留言