본문 바로가기

개발하자

테라폼으로 aws에 도메인을 등록할 수 있나요?

반응형

테라폼으로 aws에 도메인을 등록할 수 있나요?

에 유용한 것을 찾지 못했습니다. 테라폼으로 어떻게든 할 수 있을까요?




도메인 이름을 등록하는 데에는 도메인 이름 등록 기관의 최소 12개월의 약속이 포함됩니다.

Terraform과 AWS Cloud Formation과 같은 도구는 네트워크, EC2 인스턴스 및 데이터베이스와 같은 인프라스트럭처를 생성, 업데이트 및 삭제하는 데 사용됩니다.

AWS가 도메인 이름을 사용할 수 있는 기능을 제공하지만(gandi.net 을 통해 가능), 단순히 도메인 이름을 "등록 취소"할 수 없기 때문에 테라폼과 같은 도구로 수행할 수 있는 작업은 아닙니다.

이러한 도구를 사용하도록 선택할 수 있습니다. 도메인 이름을 처음 구입하는 데 적합하지 않습니다.




아래는 AWS cli를 사용하여 이를 수행하기 위한 사용자 정의 모듈이다.


README.md

묘사

이 모듈은 AWS 도메인이 사용자의 AWS 계정에 이미 등록되어 있는지 확인합니다.

도메인이 계정에 등록되지 않은 경우 등록을 시도합니다.

그런 다음 성공적으로 등록되었는지 확인합니다.

메모

도메인을 등록할 때 변수가 제공하는 등록자 정보를 사용합니다.

도메인이 등록된 후 이 모듈은 등록 속성을 동기화하지 않습니다.

즉, (1) 도메인을 등록한 다음 (2) 등록자 변수를 수정하면 변경 사항이 탐지되지 않습니다.

확인

새로운 도메인을 등록할 때는 제공한 이메일을 통해 확인해야 합니다.

등록 후 AWS로부터 제목과 함께 이메일을 받아야 합니다

도메인은 즉시 등록되며, 도메인을 상실하기 전에 이메일을 확인할 수 있는 14일의 시간이 있습니다.


variables.tf

variable "name" {
  description = "Name of the project, e.g. my-project"
  type        = string
}

variable "environment" {
  description = "The environment, e.g. prod"
  type        = string
}

variable "aws_region" {
  description = "'This command runs only in the us-east-1 region' - https://awscli.amazonaws.com/v2/documentation/api/latest/reference/route53domains/register-domain.html"
  type        = string
  default     = "us-east-1"
}

variable "auto_renew" {
  description = "Auto renew the domain when it expires, e.g. true"
  type        = bool
  default     = true
}

variable "duration_years" {
  description = "Number of years until the domain expires, e.g. 1"
  type        = number
  default     = 1
}

variable "privacy_protect_contact" {
  description = "Hide your contact details in the WHOIS record, e.g. true"
  type        = bool
  default     = true
}

variable "domain_name" {
  description = "The domain name to register, e.g. website.com"
  type        = string
}

variable "first_name" {
  description = "The first name for the registrar contact"
  type        = string
}

variable "last_name" {
  description = "The last name for the registrar contact"
  type        = string
}

variable "organization_name" {
  description = "The organization name for the registrar contact"
  type        = string
}

variable "address_line_1" {
  description = "The address for the registrar contact, e.g. 1 Main Street"
  type        = string
}

variable "city" {
  description = "The city for the registrar contact, e.g. New York City"
  type        = string
}

variable "state" {
  description = "The state for the registrar contact, e.g. NY"
  type        = string
}

variable "country_code" {
  description = "The country_code for the registrar contact, e.g. US"
  type        = string
}

variable "zip_code" {
  description = "The zip_code for the registrar contact, e.g. 10001"
  type        = string
}

variable "phone" {
  description = "The phone for the registrar contact, e.g. +1.8005551212"
  type        = string
}

variable "email" {
  description = "The email for the registrar contact, e.g. contact@website.com"
  type        = string
}

main.tf

locals {
  cli_input_json_path = "${path.module}/cli_input_json/${var.name}-${var.environment}.json"
}

resource "local_file" "cli_input_json" {
  filename = local.cli_input_json_path
  content = <<-EOF
    {
      "DomainName": "${var.domain_name}",
      "DurationInYears": ${var.duration_years},
      "AutoRenew": ${var.auto_renew},
      "PrivacyProtectAdminContact": ${var.privacy_protect_contact},
      "PrivacyProtectRegistrantContact": ${var.privacy_protect_contact},
      "PrivacyProtectTechContact": ${var.privacy_protect_contact},
      "AdminContact": {
          "ContactType": "PERSON",
          "FirstName": "${var.first_name}",
          "LastName": "${var.last_name}",
          "OrganizationName": "${var.organization_name}",
          "AddressLine1": "${var.address_line_1}",
          "City": "${var.city}",
          "State": "${var.state}",
          "CountryCode": "${var.country_code}",
          "ZipCode": "${var.zip_code}",
          "PhoneNumber": "${var.phone}",
          "Email": "${var.email}"
      },
      "RegistrantContact": {
          "ContactType": "PERSON",
          "FirstName": "${var.first_name}",
          "LastName": "${var.last_name}",
          "OrganizationName": "${var.organization_name}",
          "AddressLine1": "${var.address_line_1}",
          "City": "${var.city}",
          "State": "${var.state}",
          "CountryCode": "${var.country_code}",
          "ZipCode": "${var.zip_code}",
          "PhoneNumber": "${var.phone}",
          "Email": "${var.email}"
      },
      "TechContact": {
          "ContactType": "PERSON",
          "FirstName": "${var.first_name}",
          "LastName": "${var.last_name}",
          "OrganizationName": "${var.organization_name}",
          "AddressLine1": "${var.address_line_1}",
          "City": "${var.city}",
          "State": "${var.state}",
          "CountryCode": "${var.country_code}",
          "ZipCode": "${var.zip_code}",
          "PhoneNumber": "${var.phone}",
          "Email": "${var.email}"
      }
    }
  EOF
}

resource "null_resource" "aws_register_domain" {
  provisioner "local-exec" {
    command     = "${path.module}/aws_register_domain.sh"
    environment = {
      aws_region = var.aws_region
      domain_name = var.domain_name
      cli_input_json_path = local.cli_input_json_path
    }
  }

  depends_on = [
    local_file.cli_input_json
  ]
}

aws_register_domain.sh

#!/usr/bin/env bash
set -e


##
# Validate expected environment variables
##

if [[ -z "$aws_region" ]]; then
  echo 'aws_register_domain: no value for $aws_region' >&2
  exit 1
fi

if [[ -z "$domain_name" ]]; then
  echo 'aws_register_domain: no value for $domain_name' >&2
  exit 1
fi

if [[ -z "$cli_input_json_path" ]]; then
  echo 'aws_register_domain: no value for $cli_input_json_path' >&2
  exit 1
fi


##
# Check if domain is already registered to our account
##

echo "aws_register_domain: Checking if domain $domain_name is already registered in this AWS account"

registration_check=$(
  (
    aws route53domains get-domain-detail \
      --region "$aws_region" \
      --domain-name "$domain_name" \
      2>&1 \
  ) || :
)

# https://stackoverflow.com/a/16951928
re_escape() {
  sed 's/[][\.|$(){}?+*^]/\\&/g' <<< "$*"
}

domain_name_escaped=`re_escape "$domain_name"`
already_exists=`((echo "$registration_check" | grep -Eq 'Domain '"$domain_name_escaped"' not found in [0-9]+ account') && echo 'no') || echo 'yes'`

if [[ "$already_exists" == 'yes' ]]; then
  echo "aws_register_domain: Domain $domain_name is already registered in this AWS account"
  exit 0
elif [[ "$already_exists" == 'no' ]]; then
  found_domain_name=`echo "$registration_check" | jq -r '.DomainName'`
  if [[ "$found_domain_name" != "$domain_name" ]]; then
    echo "aws_register_domain: Expected found_domain_name to be '$domain_name' but found '$found_domain_name'" >&2
    exit 1
  fi
else
  echo "aws_register_domain: Expected already_exists to be 'yes' or 'no' but found '$already_exists'" >&2
  exit 1
fi

##
# Register the domain
##

echo "aws_register_domain: Attempting to register domain defined in '$cli_input_json_path'"

operation_id=$(
  aws route53domains register-domain \
    --region "$aws_region" \
    --cli-input-json "file://$cli_input_json_path" \
  | jq -r '.OperationId'
)

if [[ -z "$operation_id" ]]; then
  echo 'aws_register_domain: no OperationId returned' >&2
  exit 1
fi

echo "aws_register_domain: Pending registration's OperationId = $operation_id"


##
# Wait while domain registration is IN_PROGRESS
##

while true; do
  operation_info=$(
    aws route53domains get-operation-detail \
      --region "$aws_region" \
      --operation-id "$operation_id"
  )

  operation_status=`echo "$operation_info" | jq -r '.Status'`
  if [[ "$operation_status" != 'IN_PROGRESS' ]]; then
    break
  fi

  sleep 10
end


##
# Validate successful domain registration
##

echo "aws_register_domain: Registration finished with $operation_info"

expected_status='SUCCESSFUL'
if [[ "$operation_status" != "$expected_status" ]]; then
  echo "aws_register_domain: Expected final status of '$expected_status' but found '$operation_status'" >&2
  exit 1
fi

반응형