도메인 사용 정적 호스팅은 웹사이트 제공을 위해 스토리지 버킷을 사용하여 간단한 사이트를 만드는 간단한 정적 웹사이트 제작 도구입니다.
- 스토리지 - 파일 스토리지 - Cloud Storage
- 네트워킹 - 부하 분산 - Cloud 부하 분산기
- 네트워킹 - DNS - Cloud DNS
- 도메인 관리 - 등록기관 - Cloud Domains
시작하기
Cloud Shell에서 소스 코드의 복사본에 대해 다음 링크를 클릭합니다. 링크에 도착한 다음 단일 명령어로 프로젝트에서 애플리케이션의 작업 복사본이 작동합니다.
도메인 사용 정적 호스팅 구성요소
도메인 사용 정적 호스팅 아키텍처에는 여러 제품이 사용됩니다. 다음은 관련 동영상 링크, 제품 문서 및 대화형 둘러보기를 포함하여 구성 요소에 대한 자세한 정보와 함께 구성요소 목록을 보여줍니다.스크립트
설치 스크립트는 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 인증서 만들기
SSL 인증서는 https 프로토콜 요청에 필요합니다. 그러면 나중에 명령어에서 부하 분산기에 연결하는 인증서가 생성됩니다.
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]
}
A 레코드 설정
Cloud DNS에서 도메인 이름이 생성된 IP 주소로 확인되게 만드는 적절한 규칙을 만듭니다.
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
}
결론
이제 도메인 및 보안 정적 사이트를 사용하여 작은 웹사이트가 설정되었습니다. 또한 환경에 맞게 이 솔루션을 수정하거나 확장할 수 있도록 모든 코드가 준비되었습니다.