Pour un premier test, on va créer un bucket GCP, y mettre des fichiers statiques (HTML, JS, CSS, Images) et l’exposer sur Internet.

Le bucket

Tout d’abord, on crée un bucket Cloud Storage.

Ensuite, il faut associer au bucket une politique d’accès.*

Ici, on veut le rendre public, ce qui n’est pas le cas par défaut, bien sûr.

# bucket.tf

resource "google_storage_bucket" "static_sites" {
  name          = var.bucket_name
  location      = var.location
  force_destroy = true

  uniform_bucket_level_access = true

  website {
    main_page_suffix = "index.html"
    not_found_page   = "404.html"
  }
  cors {
    method          = ["GET", "HEAD", "PUT", "POST", "DELETE"]
    response_header = ["*"]
    max_age_seconds = 86400
  }
}

resource "google_storage_bucket_iam_binding" "everyoneview" {
  bucket  = var.bucket_name
  role    = "roles/storage.objectViewer"
  members = [
    "allUsers",
  ]
}

Parfois, il faut appliquer le Terraform en plusieurs fois car le bucket doit être créé pour pouvoir appliquer la politique dessus.

Vous pouvez soit écrire le fichier en deux temps, soit appliquer le TF, passer outre l’erreur et le ré-appliquer.

tf plan
tf apply # -> Crée le bucket et retourne une erreur pour le binding
tf apply # -> Ok

Réseautage

Côté réseau, nous allons exposer le bucket sur un port 443/HTTPS derrière un LoadBalancer.

Pour ça, il nous faudra déjà créer un VPC, un réseau virtuel isolé.

VPC

Le VPC est un réseau virtuel dans lequel nous allons déclarer des sous-réseaux avec une plage IP définie.

resource "google_compute_network" "vpc_network" {
  name                    = var.network_name
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "default" {
  name          = var.subnet_name
  ip_cidr_range = var.subnet_range
  region        = var.region
  network       = google_compute_network.vpc_network.id
}

Exposition avec un LoadBalancer

Dans la partie exposition, nous devons demander une IP publique et créer un load balancer externe qui redirige vers le backend (bucket).

Il faut également une url_map qui fait correspondre des chemins d’appels à des backends.

# lb.tf
resource "google_compute_global_address" "ip_address" {
  name = "my-public-ip"
}

resource "google_compute_backend_bucket" "static_sites" {
  name        = "sws-be-bucket"
  description = "Static Web sites bucket backend"
  bucket_name = google_storage_bucket.static_sites.name
}

# Create url map
resource "google_compute_url_map" "default" {
  name = "sws-urlmap"
  default_service = google_compute_backend_bucket.static_sites.id

  host_rule {
    hosts        = [var.domain_name]
    path_matcher = "sws-path-matcher"
  }
  path_matcher {
    name            = "sws-path-matcher"
    default_service = google_compute_backend_bucket.static_sites.id

    path_rule {
      paths   = ["/*"]
      service = google_compute_backend_bucket.static_sites.id
    }
  }
}

# Create HTTP target proxy
resource "google_compute_target_http_proxy" "default" {
  name    = "http-lb-proxy"
  url_map = google_compute_url_map.default.id
}

# Create forwarding rule
resource "google_compute_global_forwarding_rule" "default" {
  name                  = "http-lb-forwarding-rule"
  ip_protocol           = "TCP"
  load_balancing_scheme = "EXTERNAL_MANAGED"
  port_range            = "80"
  target                = google_compute_target_http_proxy.default.id
  ip_address            = google_compute_global_address.ip_address.id
}

Publier un site Web

Hello world !

Il ne reste plus qu’à placer des fichiers dans le bucket.

# index.html

<h1>Hello world !</h1>

Ici peut faire simple avec une copie gcloud mais la cible serait quand même d’avoir une CI/CD.

gcloud cp index.html gs://sws-bucket/

Récupérer l’adresse IP :

Pour récupérer l’adresse IP du load balancer, nous allons utiliser une variable de sortie Terraform :

# output.tf
    
output "instance_ip_addr" {
  value = google_compute_global_forwarding_rule.default.ip_address
}

Bien sûr, l’idée finale serait d’avoir un nom de domaine que l’on fasse pointer vers cette IP.

Appliquer tout ça

terraform plan
terraform apply

Gràce à l’output, vous allez récupérer l’IP.

instance_ip_addr = "11.22.33.44"

Il suffit d’aller dessus pour voir : http://11.22.33.44