Contents

TerraformでRoute53を管理してみたメモ

これまではroadworkRoute53を管理していたのですが、お仕事関係のこともあってTerraformを利用して、Route53を管理してみようと思いたち、始めてみました。

前提とする環境

前提とする環境は以下になります:

1
2
3
4
5
kazu634@bastion2004% cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.3 LTS"

インストール

ここを参考にしてインストールを行います。ログはこちら:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
kazu634@bastion2004% sudo apt-get update && sudo apt-get install -y gnupg software-properties-common curl
[sudo] kazu634 のパスワード:
ヒット:1 http://192.168.10.200:8080/ubuntu/apt-mirror/mirror/jp.archive.ubuntu.com/ubuntu focal InRelease
ヒット:2 http://192.168.10.200:8080/ubuntu/apt-mirror/mirror/jp.archive.ubuntu.com/ubuntu focal-updates InRelease
ヒット:3 http://192.168.10.200:8080/ubuntu/apt-mirror/mirror/jp.archive.ubuntu.com/ubuntu focal-backports InRelease
ヒット:4 http://192.168.10.200:8080/ubuntu/apt-mirror/mirror/jp.archive.ubuntu.com/ubuntu focal-security InRelease
ヒット:5 https://download.docker.com/linux/ubuntu focal InRelease
ヒット:6 https://apt.releases.hashicorp.com focal InRelease
ヒット:7 http://ppa.launchpad.net/git-core/ppa/ubuntu focal InRelease
ヒット:8 https://packages.grafana.com/oss/deb stable InRelease
パッケージリストを読み込んでいます... 完了
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
curl はすでに最新バージョン (7.68.0-1ubuntu2.7) です。
gnupg はすでに最新バージョン (2.2.19-3ubuntu2.1) です。
software-properties-common はすでに最新バージョン (0.98.9.5) です。
software-properties-common は手動でインストールしたと設定されました。
アップグレード: 0 個、新規インストール: 0 個、削除: 0 個、保留: 0 個。
kazu634@bastion2004% curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
OK
kazu634@bastion2004% sudo apt-get update && sudo apt-get install terraform
ヒット:1 http://192.168.10.200:8080/ubuntu/apt-mirror/mirror/jp.archive.ubuntu.com/ubuntu focal InRelease
ヒット:2 http://192.168.10.200:8080/ubuntu/apt-mirror/mirror/jp.archive.ubuntu.com/ubuntu focal-updates InRelease
ヒット:3 http://192.168.10.200:8080/ubuntu/apt-mirror/mirror/jp.archive.ubuntu.com/ubuntu focal-backports InRelease
ヒット:4 http://192.168.10.200:8080/ubuntu/apt-mirror/mirror/jp.archive.ubuntu.com/ubuntu focal-security InRelease
ヒット:5 https://download.docker.com/linux/ubuntu focal InRelease
ヒット:6 https://apt.releases.hashicorp.com focal InRelease
ヒット:7 http://ppa.launchpad.net/git-core/ppa/ubuntu focal InRelease
ヒット:8 https://packages.grafana.com/oss/deb stable InRelease
パッケージリストを読み込んでいます... 完了
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
  terraform
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 0 個。
32.7 MB のアーカイブを取得する必要があります。
この操作後に追加で 79.3 MB のディスク容量が消費されます。
取得:1 https://apt.releases.hashicorp.com focal/main amd64 terraform amd64 1.0.9 [32.7 MB]
32.7 MB を 2秒 で取得しました (21.2 MB/s)
以前に未選択のパッケージ terraform を選択しています。
(データベースを読み込んでいます ... 現在 178635 個のファイルとディレクトリがインストールされています。)
.../terraform_1.0.9_amd64.deb を展開する準備をしています ...
terraform (1.0.9) を展開しています...
terraform (1.0.9) を設定しています ...

動作確認はこんな感じで行います:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
kazu634@bastion2004% terraform -help
Usage: terraform [global options] <subcommand> [args]

The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.

Main commands:
  init          Prepare your working directory for other commands
  validate      Check whether the configuration is valid
  plan          Show changes required by the current configuration
  apply         Create or update infrastructure
  destroy       Destroy previously-created infrastructure

All other commands:
  console       Try Terraform expressions at an interactive command prompt
  fmt           Reformat your configuration in the standard style
  force-unlock  Release a stuck lock on the current workspace
  get           Install or upgrade remote Terraform modules
  graph         Generate a Graphviz graph of the steps in an operation
  import        Associate existing infrastructure with a Terraform resource
  login         Obtain and save credentials for a remote host
  logout        Remove locally-stored credentials for a remote host
  output        Show output values from your root module
  providers     Show the providers required for this configuration
  refresh       Update the state to match remote systems
  show          Show the current state or a saved plan
  state         Advanced state management
  taint         Mark a resource instance as not fully functional
  test          Experimental support for module integration testing
  untaint       Remove the 'tainted' state from a resource instance
  version       Show the current Terraform version
  workspace     Workspace management

Global options (use these before the subcommand, if any):
  -chdir=DIR    Switch to a different working directory before executing the
                given subcommand.
  -help         Show this help output, or the help for a specified subcommand.
  -version      An alias for the "version" subcommand.

TerraformでRoute53を管理する

ここからTerraformRoute53を管理していきます。

tfファイルの作成

新しくディレクトリを作成し、ここでtfファイルの作成をしていきます。main.tfをこのように作成していきます:

1
2
3
4
5
provider "aws" {
  region = "ap-northeast-1"
  access_key = "very-very-secret"
  secret_key = "very-very-secret"
}

terraform initの実行

main.tfファイルが格納されているディレクトリで、terraform initを実行します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
kazu634@bastion2004% terraform init
Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v3.63.0...
- Installed hashicorp/aws v3.63.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

AWSから現状の定義をインポートする

terraform importコマンドを実行すると、AWSから現状の定義をインポートできるということで、インポートしてみました。

なお、Terraformは実行した結果をステートファイルというファイルに格納して、そのステートファイルに記載の状態を正として変更点を洗い出します。ここが実際の状況と食い違っていると、悲劇が始まります。。

現状の定義をterraformコマンドでインポートするには、事前にmain.tfで空のリソース定義を記載する必要があります。route53で定義できるリソースは二種類あります。

  1. zone: DNSゾーンを定義します
  2. record: DNSレコードを定義します

これらの空の定義を、route53上のゾーン、レコード定義分作成してあげます。

zoneの空の定義

zoneの定義は以下のようになります:

1
resource "aws_route53_zone" "kazu634" {}

recordの空の定義

recordの定義は以下のようになります:

1
resource "aws_route53_record" "blog-a" {}

terraformコマンドによるインポート

terraformコマンドでインポートする方法を説明します。

zoneのインポート

zoneをインポートする際は、次のコマンドを実行します: terraform import aws_route53_zone.xxx <Hosted-Zone-ID>

xxxにはmain.tfで指定したzone定義のリソース名を指定します。私はこのように指定したので、

1
resource "aws_route53_zone" "kazu634" {}

xxxにはkazu634を指定します。<Hosted-Zone-ID>には、AWS Consoleから、Route53を開いて、ゾーン定義の詳細部分でIDを調べます:

https://farm66.staticflickr.com/65535/51658897950_d0431b7ffb_c.jpg

これでインポートの準備ができました。次のようにコマンドを実行すると、インポートできます。

1
$ terraform import aws_route53_zone.kazu634 ZI0FHD0611WVA

recordのインポート

recordをインポートする場合は、次のコマンドを実行します: terraform import aws_route53_record.<レコード名> <Hosted-Zone-ID>_<FQDN>_<レコード種別>

レコード名には、main.tfファイルに記載の名称を指定します。例えば、次のレコード名にインポートする場合は、

1
resource "aws_route53_record" "blog-a" {}

blog-aがレコード名になります。

Route53上でblog.kazu634.comをレコード登録している場合は、FQDNblog.kazu634.comになります。レコード種別は、DNSレコードの種別です。Aレコードとか、CNAMEレコードとかです。

例えば、Aレコードをインポートする場合は、こんな感じでインポートします。

1
$ terraform import aws_route53_record.blog-caa ZI0FHD0611WVA_blog.kazu634.com_A

このインポート作業を既存レコードの数、実施します。

準備完了

Route53に登録しているゾーン、レコード分インポートを行ったら、ステートファイルの準備はできました。

この状態でterraform planコマンドを実行すると、main.tfファイルの中身が空のため、エラーになります。リソース定義の中身を入れていき、terraform planコマンドで差分がなくなるようにしましょう。

例えばblog.kazu634.comの場合は、このように記載しました:

1
2
3
4
5
6
7
resource "aws_route53_record" "blog-a" {
  zone_id = aws_route53_zone.kazu634.zone_id
  name    = "blog.kazu634.com"
  records = ["52.193.98.253"]
  ttl     = 3600
  type    = "A"
}

振り返り

今回はroadworkerで管理していたものからの移行でしたが、手間を考えると0から設定を作っていく方がお手軽ですね。もっと簡単に既存のRoute53定義をTerraformに落とし込んでいけると良いのですが。

参考リンク