Hosting Statis dengan Domain

Arsitektur

Static Hosting with Domain adalah pembuat situs statis sederhana yang membuat situs sederhana menggunakan Bucket Storage untuk menayangkan situs:

  • Penyimpanan - Penyimpanan File - Cloud Storage
  • Jaringan - Load Balancing - Cloud Load Balancer
  • Jaringan - DNS - Cloud DNS
  • Pengelolaan Domain - Registrar - Cloud Domains

Mulai

Klik link berikut untuk mendapatkan salinan kode sumber di Cloud Shell. Setelah ada, satu perintah akan menjalankan salinan aplikasi yang berfungsi di project Anda..

Buka di Cloud Shell

Lihat kode sumber di GitHub


Hosting Statis dengan komponen Domain

Arsitektur Hosting Statis dengan Domain menggunakan beberapa produk. Berikut ini daftar komponen, beserta informasi selengkapnya tentang komponen, termasuk link ke video terkait, dokumentasi produk, dan panduan interaktif.
Video Dokumen Panduan
Cloud Storage Cloud Storage menyediakan penyimpanan file dan penyajian gambar secara publik melalui http.
Cloud DNS Cloud DNS menyediakan pengelolaan DNS - yang memungkinkan Anda menjalankan infrastruktur DNS Anda sendiri menggunakan infrastruktur DNS Google yang ada.
Cloud Load Balancing Dengan Load Balancer Google Cloud, Anda dapat menempatkan load balancer di depan Bucket Storage, sehingga Anda dapat menggunakan sertifikat SSL, Logging, dan Monitoring.
Domain Cloud Cloud Domains memungkinkan Anda membeli domain dengan peran seperti Registrar Domain - tetapi setelah melakukannya, Anda dapat mengelola domain tersebut dan menangani penagihan melalui Akun Google Cloud Anda.

Skrip

Skrip penginstalan menggunakan file yang dapat dieksekusi yang ditulis di alat CLI Terraform dan go untuk mengambil project kosong dan menginstal aplikasi di dalamnya. Output harus berupa aplikasi yang berfungsi dan URL untuk alamat IP load balancing.

./main.tf

Aktifkan Layanan

Layanan Google Cloud dinonaktifkan dalam project secara default. Untuk menggunakan salah satu solusi di sini, kita harus mengaktifkan hal berikut:

  • Cloud Domains - pendaftaran domain
  • Cloud Storage - menghosting file statis
  • Cloud Compute - menyediakan akses ke load balancer.
  • Cloud DNS - menyediakan pengelolaan 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
}

Buat Zona DNS

Membuat Zona DNS untuk mengelola data, mengarahkannya ke load balancer, berinteraksi dengan Registrar Domain, dan menyalurkan permintaan DNS ke server DNS lainnya.

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}"
}

Buat Sertifikat SSL

Sertifikat SSL diperlukan untuk permintaan protokol HTTPS. Ini akan menghasilkan satu yang akan dilampirkan ke load balancer di perintah berikutnya.

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
    }
}

Buat Alamat IP Eksternal

Diperlukan untuk mengikat host ke nama domain, dan berkomunikasi secara umum di Internet.

resource "google_compute_global_address" "ip" {
    project    = var.project_id
    name       = "${local.basename}-ip"
    ip_version = "IPV4"
}

Membuat Bucket Penyimpanan

Tindakan ini akan membuat bucket yang diberi nama berdasarkan domain, lalu menyiapkan bucket dengan konfigurasi yang tepat untuk berfungsi sebagai server web. Terakhir, fitur ini menyalin {i>template <i}sederhana untuk situs.

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,
    ]
}

Load Balancer Berdiri

Tindakan ini akan membuat load balancer dan menyiapkan Bucket Penyimpanan sebagai sumber konten yang akan diberikan akses oleh load balancer.

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]
}

Aktifkan HTTP

Membuat aturan jaringan yang diperlukan untuk mengarahkan port 80 pada load balancer ke layanan yang sedang kita jalankan.

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]
}

Mengaktifkan HTTPS

Membuat aturan jaringan yang diperlukan untuk mengarahkan port 443 pada load balancer ke layanan yang sedang kita jalankan. Juga mengaitkan sertifikat dengan benar.

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]
}

Setel Catatan

Membuat aturan yang tepat di Cloud DNS yang akan membuat nama domain me-resolve ke alamat IP yang kita buat.

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

Ketersediaan Domain Kueri

Mendapatkan informasi tentang ketersediaan domain yang diminta

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
}

Kepemilikan Domain Kueri

Mendapatkan informasi apakah pengguna saat ini memiliki domain yang diminta atau tidak.

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
}

Daftarkan Domain dengan Cloud Domains

Sebenarnya melakukan operasi untuk membeli domain dari {i>registrar<i}.

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
}


Kesimpulan

Anda kini memiliki penyiapan situs kecil dengan domain dan situs statis yang aman. Selain itu, Anda harus memiliki semua kode untuk memodifikasi atau memperluas solusi ini agar sesuai dengan lingkungan Anda.