rubyのaws-sdkでRoute53にレコード登録

rubyのaws-sdkを使ってRoute53にレコードを登録するサンプルです。


### 基本的なサンプル

#### Aレコードの登録

こんな感じです。

```rb
#!/usr/bin/env ruby
require 'aws-sdk'

domain = 'mikeda.info.'
fqdn   = 'test02.mikeda.info'
value  = '10.0.0.1'

r53 = AWS::Route53.new

hosted_zone = r53.hosted_zones.find {|z| z.name == domain }
hosted_zone.rrsets.create(
  fqdn,
  'A',
  ttl: 300,
  resource_records: [
    { value: value }
  ]
)
```

これを実行すると、

```
$ export AWS_ACCESS_KEY_ID=XXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXX
$ ruby rds_test_a.rb
```

Route53にレコードが登録されます。

![rds_test.png](https://qiita-image-store.s3.amazonaws.com/0/20279/1814666a-96c8-f1be-6c5b-2acda78bc089.png)

#### CNAMEの登録

Aレコードとほとんど同じです。

```rb
#!/usr/bin/env ruby
require 'aws-sdk'

domain = 'mikeda.info.'
fqdn = 'cname-test01.mikeda.info'
value = 'test01.mikeda.info.'

r53 = AWS::Route53.new

hosted_zone = r53.hosted_zones.find {|z| z.name == domain }
hosted_zone.rrsets.create(
  fqdn,
  'CNAME',
  ttl: 300,
  resource_records: [
    { value: value }
  ]
)
```


### 実践的なサンプル

自分は小規模なシステムだと、EC2インスタンス作成時にEIPを取得、アタッチして、そのパブリックDNS名をCNAMEとしてRoute53に登録してしまうことが多いです。
その場合はRoute53を内部DNSとしても使います。

インスタンス作成スクリプトはこんな感じになります。

```rb
#!/usr/bin/env ruby

require 'aws-sdk'

hostname = 'test02'
domain   = 'mikeda.info.'

region = 'ap-northeast-1'
vpc    = 'vpc-4c6f2825'
subnet = 'subnet-77f0841f'

image_id = 'ami-29dc9228' # Amazon Linux
instance_type = 't2.micro'
key_name = 'mikeda'
security_group_ids = [
  'sg-d65d42ba', # default
]
iam_instance_profile = 'default'
ebs_size = 20

AWS.config( region: region )

### EC2インスタンスを作成
ec2 = AWS::EC2.new

instance = ec2.instances.create(
  image_id:        image_id,
  instance_type:   instance_type,
  key_name:        key_name,
  subnet:          subnet,
  security_group_ids: security_group_ids,
  iam_instance_profile: iam_instance_profile,
  block_device_mappings: [
    {
      device_name: '/dev/xvda',
      ebs: { volume_size: ebs_size }
    }
  ]
)

while instance.status != :running
  puts "Launching instance #{instance.id}, status: #{instance.status}"
  sleep 5
end

### EIPのAllocateとAssociate
elastic_ip = ec2.elastic_ips.create(vpc: vpc)
sleep 5 # なんかエラーになるのでちょっとsleep
instance.associate_elastic_ip(elastic_ip)

puts "associated EIP : #{elastic_ip.ip_address}"

### Route53にレコード追加
fqdn = "#{hostname}.#{domain}"

r53 = AWS::Route53.new
hosted_zone = r53.hosted_zones.find { |z| z.name == domain }
hosted_zone.rrsets.create(
  fqdn,
  'CNAME',
  ttl: 300,
  resource_records: [
    { value: instance.public_dns_name}
  ]
)

puts "add CNAME Record to Route53 : #{fqdn}"
```

実行するとインスタンス作成、EIPの取得とアタッチ、Route53のレコード登録まで完了します。

```
$ export AWS_ACCESS_KEY_ID=XXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXX
$ ruby create_ec2_instance_test.rb
Launching instance i-a18c31b8, status: pending
Launching instance i-a18c31b8, status: pending
Launching instance i-a18c31b8, status: pending
associated EIP : 54.64.106.117
add CNAME Record to Route53 : test02.mikeda.info.
```

こうしておくと、外部から名前解決するとグローバルIPが取得できて、

```
$ dig test02.mikeda.info
...

;; ANSWER SECTION:
test02.mikeda.info.	377	IN	CNAME	ec2-54-64-106-117.ap-northeast-1.compute.amazonaws.com.
ec2-54-64-106-117.ap-northeast-1.compute.amazonaws.com.	756002 IN A 54.64.106.117

$ ssh ec2-user@test02.mikeda.info
[ec2-user@test02 ~]$
```

VPC内から名前解決するとローカルIPが取得できます。

```
$ ssh ec2-user@test01.mikeda.info
[ec2-user@test01 ~]$ dig test02.mikeda.info
...

;; ANSWER SECTION:
test02.mikeda.info.	300	IN	CNAME	ec2-54-64-106-117.ap-northeast-1.compute.amazonaws.com.
ec2-54-64-106-117.ap-northeast-1.compute.amazonaws.com.	60 IN A	10.0.2.190
```