Adding a Cloud Armor example

This example shows how to build a network with a simple back end that
can be black/white listed by ip address.
This commit is contained in:
Chris Stephens 2018-08-08 16:02:15 -07:00
parent a0e0afc537
commit 93a8d9ce27
4 changed files with 210 additions and 0 deletions

3
examples/cloud-armor/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
terraform.tfstate
terraform.tfstate.backup
terraform.tfvars

View File

@ -0,0 +1,19 @@
# White listing IP's using Cloud Armor
This is an example of setting up a project to take advantage of one of the [Cloud Armor features](https://cloud.google.com/armor/) that allows whitelisting of traffic to a compute instance based on ip address. It will set up a single compute instance running nginx that is accessible via a load balanced pool that is managed by cloud armor security policies.
To run the example:
* Set up a Google Cloud Platform account with the [compute engine api enabled](https://cloud.google.com/endpoints/docs/openapi/enable-api)
* [Configure the Google Cloud Provider credentials](https://www.terraform.io/docs/providers/google/index.html#credentials)
* Update the `variables.tf` OR provide overrides in the command line
* Run with a command similar to:
```
terraform apply \
-var="region=us-west1" \
-var="region_zone=us-west1-a" \
-var="project_name=my-project-id-123" \
```
After running `terraform apply` the external ip address of the load balancer will be output to the console. Either enter the ip address into the browser directly or add it to the hosts file on your machine so that it can be accessed at 'mysite.com'.
Navigating to the address either way should result in a 403 rejection. Change the ip address in the whitelist rule in `main.tf` to a local ip address or range and re-run `terraform apply` to be able to hit the nginx welcome page on the instance. Note: it can take a little while before the changes apply.

View File

@ -0,0 +1,172 @@
# Example for using Cloud Armor https://cloud.google.com/armor/
#
resource "random_id" "instance_id" {
byte_length = 4
}
# Configure the Google Cloud provider
provider "google" {
credentials = "${file(var.credentials_file_path)}"
project = "${var.project_name}"
region = "${var.region}"
zone = "${var.region_zone}"
}
# Set up a backend to be proxied to:
# A single instance in a pool running nginx with port 80 open will allow end to end network testing
resource "google_compute_instance" "cluster1" {
name = "armor-gce-${random_id.instance_id.hex}"
machine_type = "f1-micro"
boot_disk {
initialize_params {
image = "debian-cloud/debian-9"
}
}
network_interface {
network = "default"
access_config = {
# Ephemeral IP
}
}
metadata_startup_script = "sudo apt-get update; sudo apt-get install -yq nginx; sudo service nginx restart"
}
resource "google_compute_firewall" "cluster1" {
name = "cloud-armor-firewall"
network = "default"
allow {
protocol = "tcp"
ports = ["80", "43"]
}
}
resource "google_compute_instance_group" "webservers" {
name = "instance-group-all"
description = "An instance group for the single GCE instance"
instances = [
"${google_compute_instance.cluster1.self_link}",
]
named_port {
name = "http"
port = "80"
}
}
resource "google_compute_target_pool" "example" {
name = "armor-pool"
instances = [
"${google_compute_instance.cluster1.self_link}",
]
health_checks = [
"${google_compute_http_health_check.health.name}",
]
}
resource "google_compute_http_health_check" "health" {
name = "armor-healthcheck"
request_path = "/"
check_interval_sec = 1
timeout_sec = 1
}
resource "google_compute_backend_service" "website" {
name = "armor-backend"
description = "Our company website"
port_name = "http"
protocol = "HTTP"
timeout_sec = 10
enable_cdn = false
backend {
group = "${google_compute_instance_group.webservers.self_link}"
}
security_policy = "${google_compute_security_policy.security-policy-1.self_link}"
health_checks = ["${google_compute_http_health_check.health.self_link}"]
}
# Cloud Armor Security policies
resource "google_compute_security_policy" "security-policy-1" {
name = "armor-security-policy"
description = "example security policy"
# Reject all traffic that hasn't been whitelisted.
rule {
action = "deny(403)"
priority = "2147483647"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
description = "Default rule, higher priority overrides it"
}
# Whitelist traffic from certain ip address
rule {
action = "allow"
priority = "1000"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["192.0.2.0/24"]
}
}
description = "allow traffic from 192.0.2.0/24"
}
}
# Front end of the load balancer
resource "google_compute_global_forwarding_rule" "default" {
name = "default-rule"
target = "${google_compute_target_http_proxy.default.self_link}"
port_range = "80"
}
resource "google_compute_target_http_proxy" "default" {
name = "test-proxy"
description = "a description"
url_map = "${google_compute_url_map.default.self_link}"
}
resource "google_compute_url_map" "default" {
name = "url-map"
description = "a description"
default_service = "${google_compute_backend_service.website.self_link}"
host_rule {
hosts = ["mysite.com"]
path_matcher = "allpaths"
}
path_matcher {
name = "allpaths"
default_service = "${google_compute_backend_service.website.self_link}"
path_rule {
paths = ["/*"]
service = "${google_compute_backend_service.website.self_link}"
}
}
}
output "ip" {
value = "${google_compute_global_forwarding_rule.default.ip_address}"
}

View File

@ -0,0 +1,16 @@
variable "region" {
default = "us-west1"
}
variable "region_zone" {
default = "us-west1-a"
}
variable "project_name" {
description = "The ID of the Google Cloud project"
}
variable "credentials_file_path" {
description = "Path to the JSON file used to describe your account credentials"
default = "~/.gcloud/Terraform.json"
}