Static Hosting with Domain è un semplice creatore di siti web statici che crea un sito semplice utilizzando un bucket di archiviazione per la gestione del sito web.
- Spazio di archiviazione - Archiviazione di file - Cloud Storage
- Networking - Bilanciamento del carico - Bilanciatore del carico Cloud
- Networking - DNS - Cloud DNS
- Gestione del dominio - Registrar - Cloud Domains
Inizia
Fai clic sul seguente link che rimanda a una copia del codice sorgente in Cloud Shell. Una volta eseguito l'accesso, un singolo comando genererà una copia funzionante dell'applicazione nel tuo progetto.
Visualizza il codice sorgente su GitHub
Hosting statico con componenti di dominio
L'architettura di hosting statico con dominio utilizza diversi prodotti. Di seguito sono elencati i componenti, insieme a ulteriori informazioni sui componenti, inclusi i link ai video correlati, la documentazione del prodotto e le procedure dettagliate interattive.Script
Lo script di installazione utilizza un file eseguibile scritto in strumenti go
dell'interfaccia a riga di comando di Terraform e Terraform per eseguire un progetto vuoto e installare l'applicazione al suo interno. L'output dovrebbe essere un'applicazione funzionante e un URL per l'indirizzo IP di bilanciamento del carico.
./main.tf
Attiva i servizi
I servizi Google Cloud sono disabilitati per impostazione predefinita in un progetto. Per utilizzare una qualsiasi delle soluzioni qui, dobbiamo attivare quanto segue:
- Cloud Domains - Registrazione del dominio
- Cloud Storage: hosting dei file statici
- Cloud Compute: fornisce l'accesso ai bilanciatori del carico.
- Cloud DNS: offre la gestione del 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
}
Crea zona DNS
Crea una zona DNS per la gestione dei record, indirizzandoli verso i bilanciatori del carico, interagendo con i registrar di domini e erogando le richieste DNS ad altri server 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}"
}
Crea certificato SSL
Per le richieste di protocollo https sono necessari i certificati SSL. Questo genera uno che verrà collegato al bilanciatore del carico in un comando successivo.
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
}
}
Crea indirizzo IP esterno
necessaria per associare un host al nome di dominio e comunicare in generale su Internet.
resource "google_compute_global_address" "ip" {
project = var.project_id
name = "${local.basename}-ip"
ip_version = "IPV4"
}
Crea bucket di archiviazione
Viene creato un bucket denominato in base al dominio, quindi viene configurato con la configurazione adeguata per agire come un server web. Infine, copia il modello semplice per il sito
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,
]
}
Bilanciatore del carico
Questo crea il bilanciatore del carico e configura il bucket di archiviazione come l'origine dei contenuti a cui il bilanciatore del carico fornirà l'accesso.
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]
}
Attiva HTTP
Crea le regole di networking necessarie per indirizzare la porta 80 sul bilanciatore del carico al servizio in esecuzione.
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]
}
Attiva HTTPS
Crea le regole di networking necessarie per indirizzare la porta 443 sul bilanciatore del carico al servizio in esecuzione. Inoltre, associa il certificato correttamente.
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]
}
Imposta un record
Crea la regola corretta in Cloud DNS che consentirà la risoluzione del nome di dominio nell'indirizzo IP che abbiamo creato.
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
Disponibilità del dominio della query
Recupera le informazioni sulla disponibilità del dominio richiesto
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
}
Esegui query su proprietà dominio
Recupera le informazioni che indicano se l'utente corrente possiede o meno il dominio richiesto.
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
}
Registra dominio con Cloud Domains
Di fatto esegue l'operazione per acquistare il dominio dal registrar.
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
}
Conclusione
Ora hai una configurazione del sito web di piccole dimensioni con un dominio e un sito statico e sicuro. Inoltre, dovresti avere tutto il codice per modificare o estendere questa soluzione in base all'ambiente.