ドメインを使用した静的ホスティングは、シンプルな静的ウェブサイト作成者であり、ウェブサイトを提供するためのストレージ バケットを使用するシンプルなサイトを作成します。
- ストレージ - ファイル ストレージ - Cloud Storage
- ネットワーキング - ロード バランシング - Cloud ロードバランサ
- ネットワーキング - DNS - Cloud DNS
- ドメイン管理 - 登録事業者 - Cloud Domains
スタートガイド
Cloud Shell でソースコードのコピーへの次のリンクをクリックします。その後、1 つのコマンドでプロジェクト内のアプリケーションの作業コピーがスピンアップされます。
ドメインを使用した静的ホスティングのコンポーネント
ドメインと静的ホスティングのアーキテクチャでは、いくつかのプロダクトを使用しています。 以下に、関連動画、プロダクト ドキュメント、インタラクティブ チュートリアルへのリンクを含めた、コンポーネントの詳細を示します。スクリプト
インストール スクリプトでは、go
と Terraform CLI ツールで記述された実行ファイルを使用して、空のプロジェクトを作成し、そこにアプリケーションをインストールします。出力は、機能するアプリケーションとロード バランシング IP アドレスの URL になります。
./main.tf
サービスを有効化する
Google Cloud サービスは、デフォルトではプロジェクトで無効になっています。ここに記載されているいずれかのソリューションを使用するには、以下の対象を有効にする必要があります。
- Cloud Domains - ドメイン登録
- Cloud Storage - 静的ファイルをホストする
- Cloud Compute - ロードバランサへのアクセスを提供する
- Cloud DNS - 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
}
DNS ゾーンを作成する
レコードを管理するための DNS ゾーンを作成します。レコードをロードバランサで参照し、ドメイン レジストラとやり取りして、他の DNS サーバーに対して 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}"
}
SSL 証明書を作成する
https プロトコル リクエストには SSL 証明書が必要です。次のコマンドでは、ロードバランサに接続される SSL 証明書が生成されます。
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
}
}
外部 IP アドレスを作成する
ホストをドメイン名にバインドし、一般的にインターネット上で通信する必要があります。
resource "google_compute_global_address" "ip" {
project = var.project_id
name = "${local.basename}-ip"
ip_version = "IPV4"
}
ストレージ バケットを作成する
これにより、ドメインの名前が付けられたバケットが作成され、ウェブサーバーとして機能するようにバケットが適切に構成されます。最後に、サイトのシンプルなテンプレートをコピーします。
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,
]
}
ロードバランサの起動
以下により、ロードバランサが作成され、ロードバランサがアクセス権を提供するコンテンツのソースとしてストレージ バケットが設定されます。
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]
}
HTTP を有効にする
ロードバランサのポート 80 が実行中のサービスを指すように、必要なネットワーク ルールを作成します。
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]
}
HTTPS を有効にする
ロードバランサのポート 443 が実行中のサービスを指すように、必要なネットワーク ルールを作成します。また、証明書を適切に関連付けます。
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]
}
レコードを設定する
ドメイン名が作成した IP アドレスに解決されるように、Cloud DNS に適切なルールを作成します。
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
ドメインの可用性をクエリする
リクエストされたドメインの可用性に関する情報を取得します。
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
}
ドメイン所有権のクエリを実行する
現在のユーザーがリクエストされたドメインを所有しているかどうかの情報を取得します。
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
}
Cloud Domains でドメインを登録する
登録事業者からドメインを購入するオペレーションを実際に実行します。
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
}
まとめ
ドメインと安全な静的サイトを配置した小規模なウェブサイトの設定が完了しました。さらに、環境に合わせてソリューションを変更または拡張するためのコードもすべて用意されています。