Static Hosting with Domain es un creador de sitios web estáticos sencillo que crea un sitio simple mediante un segmento de almacenamiento para publicar el sitio web:
- Almacenamiento - Almacenamiento de archivos - Cloud Storage
- Redes - Balanceo de carga - Balanceador de carga en la nube
- Redes - DNS - Cloud DNS
- Gestión de dominios: registrador - Cloud Domains
Empezar
Haz clic en el siguiente enlace para acceder a una copia del código fuente en Cloud Shell. Una vez allí, con un solo comando se creará una copia de trabajo de la aplicación en tu proyecto.
Ver el código fuente en GitHub
Alojamiento estático con componentes de dominio
La arquitectura de alojamiento estático con dominio utiliza varios productos. A continuación, se enumeran los componentes y se incluye más información sobre ellos, como enlaces a vídeos relacionados, documentación del producto y tutoriales interactivos.Secuencias de comandos
La secuencia de comandos de instalación usa un ejecutable escrito en go
y las herramientas de la CLI de Terraform para tomar un proyecto vacío e instalar la aplicación en él. El resultado debe ser una aplicación que funcione y una URL para la dirección IP de balanceo de carga.
./main.tf
Habilitar servicios
Los servicios de Google Cloud están inhabilitados en un proyecto de forma predeterminada. Para usar cualquiera de las soluciones que se indican a continuación, debemos activar lo siguiente:
- Cloud Domains: registro de dominios
- Cloud Storage: aloja los archivos estáticos.
- Cloud Compute: proporciona acceso a los balanceadores de carga.
- Cloud DNS: ofrece gestión de DNS.
variable "gcp_service_list" {
description = "The list of apis necessary for the project"
type = list(string)
default = [
"domains.googleapis.com",
"storage.googleapis.com",
"compute.googleapis.com",
"dns.googleapis.com",
"appengine.googleapis.com",
]
}
resource "google_project_service" "all" {
for_each = toset(var.gcp_service_list)
project = var.project_number
service = each.key
disable_dependent_services = false
disable_on_destroy = false
}
Crear zona DNS
Crea una zona DNS para gestionar registros, dirigirlos a balanceadores de carga, interactuar con registradores de dominios y atender solicitudes DNS a otros servidores DNS.
resource "google_dns_managed_zone" "dnszone" {
project = var.project_id
name = local.clouddnszone
dns_name = "${var.domain}."
description = "A DNS Zone for managing ${var.domain}"
}
Crear certificado SSL
Los certificados SSL son obligatorios para las solicitudes del protocolo https. De esta forma, se genera uno que se adjuntará al balanceador de carga en un comando posterior.
resource "google_compute_managed_ssl_certificate" "cert" {
name = "${local.basename}-cert"
description = "Cert for ${local.basename}-microsite"
project = var.project_id
managed {
domains = [var.domain]
}
lifecycle {
create_before_destroy = true
}
}
Crear una dirección IP externa
Necesario para vincular un host al nombre de dominio y comunicarse en general en Internet.
resource "google_compute_global_address" "ip" {
project = var.project_id
name = "${local.basename}-ip"
ip_version = "IPV4"
}
Crear segmento de almacenamiento
De esta forma, se crea un contenedor con el nombre del dominio y se configura correctamente para que actúe como servidor web. Por último, copia la plantilla simple del sitio.
resource "google_storage_bucket" "http_bucket" {
name = local.bucket
project = var.project_id
location = var.location
website {
main_page_suffix = "index.html"
not_found_page = "404.html"
}
}
resource "google_storage_bucket_iam_binding" "policy" {
bucket = google_storage_bucket.http_bucket.name
role = "roles/storage.objectViewer"
members = [
"allUsers",
]
depends_on = [google_storage_bucket.http_bucket]
}
resource "google_storage_bucket_object" "archive" {
name = "index.html"
bucket = google_storage_bucket.http_bucket.name
source = "code/${var.yesorno}/index.html"
depends_on = [
google_project_service.all,
google_storage_bucket.http_bucket,
]
}
Stand Up Load Balancer
De esta forma, se crea el balanceador de carga y se configura el segmento de Storage como origen del contenido al que proporcionará acceso el balanceador de carga.
resource "google_compute_backend_bucket" "be" {
project = var.project_id
name = "${local.basename}-be"
bucket_name = google_storage_bucket.http_bucket.name
depends_on = [google_storage_bucket.http_bucket]
}
resource "google_compute_url_map" "lb" {
project = var.project_id
name = "${local.basename}-lb"
default_service = google_compute_backend_bucket.be.id
depends_on = [google_compute_backend_bucket.be]
}
Habilitar HTTP
Crea las reglas de red necesarias para dirigir el puerto 80 del balanceador de carga al servicio que estamos ejecutando.
resource "google_compute_target_http_proxy" "lb-proxy" {
project = var.project_id
name = "${local.basename}-lb-proxy"
url_map = google_compute_url_map.lb.id
depends_on = [google_compute_url_map.lb]
}
resource "google_compute_forwarding_rule" "http-lb-forwarding-rule" {
project = var.project_id
name = "${local.basename}-http-lb-forwarding-rule"
provider = google-beta
region = "none"
load_balancing_scheme = "EXTERNAL"
port_range = "80"
target = google_compute_target_http_proxy.lb-proxy.id
ip_address = google_compute_global_address.ip.id
depends_on = [google_compute_target_http_proxy.lb-proxy]
}
Habilitar HTTPS
Crea las reglas de red necesarias para dirigir el puerto 443 del balanceador de carga al servicio que estamos ejecutando. También asocia el certificado correctamente.
resource "google_compute_target_https_proxy" "ssl-lb-proxy" {
project = var.project_id
name = "${local.basename}-ssl-lb-proxy"
url_map = google_compute_url_map.lb.id
ssl_certificates = [google_compute_managed_ssl_certificate.cert.id]
depends_on = [google_compute_url_map.lb,google_compute_managed_ssl_certificate.cert ]
}
resource "google_compute_forwarding_rule" "https-lb-forwarding-rule" {
project = var.project_id
name = "${local.basename}-https-lb-forwarding-rule"
provider = google-beta
region = "none"
load_balancing_scheme = "EXTERNAL"
port_range = "443"
target = google_compute_target_https_proxy.ssl-lb-proxy.id
ip_address = google_compute_global_address.ip.id
depends_on = [google_compute_target_https_proxy.ssl-lb-proxy]
}
Configurar un registro A
Crea la regla adecuada en Cloud DNS para que el nombre de dominio se resuelva en la dirección IP que hemos creado.
resource "google_dns_record_set" "a" {
project = var.project_id
name = "${var.domain}."
managed_zone = google_dns_managed_zone.dnszone.name
type = "A"
ttl = 60
rrdatas = [google_compute_global_address.ip.address]
depends_on = [google_compute_global_address.ip]
}
./deploystack.go
Consultar la disponibilidad de un dominio
Obtiene información sobre la disponibilidad del dominio solicitado.
func domainsSearch(project, domain string) ([]*domainspb.RegisterParameters, error) {
ctx := context.Background()
c, err := domains.NewClient(ctx)
if err != nil {
return nil, err
}
defer c.Close()
req := &domainspb.SearchDomainsRequest{
Query: domain,
Location: fmt.Sprintf("projects/%s/locations/global", project),
}
resp, err := c.SearchDomains(ctx, req)
if err != nil {
return nil, err
}
return resp.RegisterParameters, nil
}
func domainIsAvailable(project, domain string) (*domainspb.RegisterParameters, error) {
list, err := domainsSearch(project, domain)
if err != nil {
return nil, err
}
for _, v := range list {
if v.DomainName == domain {
return v, err
}
}
return nil, err
}
Consultar la propiedad del dominio
Obtiene información sobre si el usuario actual es el propietario del dominio solicitado.
func domainsIsVerified(project, domain string) (bool, error) {
ctx := context.Background()
c, err := domains.NewClient(ctx)
if err != nil {
return false, err
}
defer c.Close()
req := &domainspb.ListRegistrationsRequest{
Filter: fmt.Sprintf("domainName=\"%s\"", domain),
Parent: fmt.Sprintf("projects/%s/locations/global", project),
}
it := c.ListRegistrations(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
return false, err
}
if resp.DomainName == domain {
return true, nil
}
}
return false, nil
}
Registrar un dominio con Cloud Domains
Realiza la operación para comprar el dominio al registrador.
func domainRegister(project string, domaininfo *domainspb.RegisterParameters, contact ContactData) error {
ctx := context.Background()
parent := fmt.Sprintf("projects/%s/locations/global", project)
c, err := domains.NewClient(ctx)
if err != nil {
return err
}
defer c.Close()
dnscontact, err := contact.DomainContact()
if err != nil {
return err
}
req := &domainspb.RegisterDomainRequest{
Registration: &domainspb.Registration{
Name: fmt.Sprintf("%s/registrations/%s", parent, domaininfo.DomainName),
DomainName: domaininfo.DomainName,
DnsSettings: &domainspb.DnsSettings{
DnsProvider: &domainspb.DnsSettings_CustomDns_{
CustomDns: &domainspb.DnsSettings_CustomDns{
NameServers: []string{
"ns-cloud-e1.googledomains.com",
"ns-cloud-e2.googledomains.com",
"ns-cloud-e3.googledomains.com",
"ns-cloud-e4.googledomains.com",
},
},
},
},
ContactSettings: &dnscontact,
},
Parent: parent,
YearlyPrice: domaininfo.YearlyPrice,
}
if _, err := c.RegisterDomain(ctx, req); err != nil {
return err
}
return nil
}
Conclusión
Ahora tienes un pequeño sitio web configurado con un dominio y un sitio estático seguro. Además, deberías tener todo el código para modificar o ampliar esta solución y adaptarla a tu entorno.