LoginSignup
0
0

More than 5 years have passed since last update.

Route53 と roadworker を使って VPC 環境の内部DNSを構築する

Posted at

概要

AWS の VPC 環境の内部DNSに Route53 を利用するように設定して、Codenize.tools の roadworker を使って EC2 インスタンスの tag.Name で ssh したりできるようにしてみたのでその時の環境構築の時のメモです

構築環境

  • Amazon Linux AMI release 2017.09
  • ruby 2.3.5p376 (2017-09-14 revision 59905) [x86_64-linux-gnu]
  • roadwork 0.5.9.beta5

Route53 で VPC の内部DNSを構築

参考: https://cloudpack.media/9573

VPC でプライベートホストゾーンを有効化

aws ec2 modify-vpc-attribute \
  --vpc-id vpc-XXXXXXXX \
  --enable-dns-hostnames '{"Value":true}'

aws ec2 modify-vpc-attribute \
  --vpc-id vpc-XXXXXXXX \
  --enable-dns-support '{"Value":true}'

Route53 でプライベートホストゾーンを作成

aws route53 create-hosted-zone \
  --name my-sample-private-hosted-zone.internal \
  --vpc 'VPCRegion="ap-northeast-1",VPCId="vpc-XXXXXXXX"' \
  --caller-reference 2017-12-14-00:00 \
  --hosted-zone-config 'PrivateZone="true"'

DHCP オプションを作成して VPC に関連付け

aws ec2 create-dhcp-options --dhcp-configuration '[
  {
    "Key": "domain-name-servers",
    "Values": ["AmazonProvidedDNS"]
  },
  {
    "Key": "domain-name",
    "Values": ["my-sample-private-hosted-zone.internal"]
  }
]'
aws ec2 associate-dhcp-options --dhcp-options-id dopt-XXXXXXXX --vpc-id vpc-XXXXXXXX # --dhcp-options-id は aws ec2 create-dhcp-options の返り値の "DhcpOptionsId" の値

roadworker で EC2 インスタンスの tag.Name を自動で Route53 のレコードに追加できるようにする

試してみたら結構便利だったので Codenize.toolsroadworker を使って EC2 インスタンスの tag.Name を自動で Route53 のレコードに追加するようにしてみました

roadworker 用 EC2 インスタンスを作成

aws ec2 run-instances \
  --image-id ami-da9e2cbc \
  --security-group-ids sg-XXXXXX \
  --subnet-id subnet-XXXXXX \
  --count 1 \
  --instance-type m4.medium \
  --key-name sample-keyname

(事前に上記のインスタンスに ssh できるようにしておく必要があります)

対象インスタンスへ Route53 と EC2 のアクセス権を付与する IAM ポリシーを付与

aws iam create-role --role-name roadworker --assume-role-policy-document '{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Principal": {"Service": "ec2.amazonaws.com"},
    "Action": "sts:AssumeRole"
  }
}'
{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": {
                "Action": "sts:AssumeRole",
                "Effect": "Allow",
                "Principal": {
                    "Service": "ec2.amazonaws.com"
                }
            }
        },
        "RoleId": "XXXXXXXXXXXXXXXXXXXX",
        "CreateDate": "2017-12-14T00:00:00.000Z",
        "RoleName": "roadworker",
        "Path": "/",
        "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/roadworker"
    }
}

aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonRoute53FullAccess --role-name roadworker
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess --role-name roadworker
aws iam create-instance-profile --instance-profile-name roadworker
aws iam add-role-to-instance-profile --role-name roadworker --instance-profile-name roadworker
aws ec2 associate-iam-instance-profile --instance-id i-XXXXXXXXXXXXXXXXX --iam-instance-profile Name="roadworker"

--instance-id i-XXXXXXXXXXXXXXXXX は作成したインスタンスの ID となります

ruby バージョンアップ & 関連 yum install

サーバに ssh して

$ sudo su -
$ yum install -y ruby23-devel gcc libpcap-devel
$ alternatives --config ruby

There are 2 programs which provide 'ruby'.

  Selection    Command
-----------------------------------------------
*+ 1           /usr/bin/ruby2.0
   2           /usr/bin/ruby2.3

Enter to keep the current selection[+], or type selection number: 2

$ gem install bundler
$ bundle exec ruby -v
ruby 2.3.5p376 (2017-09-14 revision 59905) [x86_64-linux-gnu]

roadworker インストール

$ mkdir /usr/local/roadworker
$ cd /usr/local/roadworker
$ bundle init
$ echo "gem 'roadworker', '0.5.9.beta5'" >> Gemfile
$ echo "gem 'json'" >> Gemfile # https://github.com/tdiary/tdiary-core/issues/510 の問題が発生するため
$ bundle install
$ vi Routefile # ↓の内容で Routefile を書く

Routefile

require 'aws-sdk'
region = "ap-northeast-1"
vpc_id = "vpc-XXXXXXXX"
domain = "my-sample-private-hosted-zone.internal."

hosted_zone "my-sample-private-hosted-zone.internal." do
  vpc region, vpc_id

  resp = Aws::EC2::Client.new(region: region).describe_instances(filters:[{ name: 'vpc-id', values: [vpc_id] }])
  instances = resp.reservations.each_with_object({}) do |reservation, reservations|
    reservations.merge!(reservation.instances.each_with_object({}) do |instance, instances|
      instances[instance.private_ip_address] = instance.tags.find {|tag| tag['key'] == 'Name' }['value']
    end)
  end

  instances.each {|private_ip_address, tagName|
    rrset "#{tagName}.#{domain}", "A" do
      ttl 60
      resource_records private_ip_address
    end
  }
end

作成した Routefile を適用

$ bundle exec roadwork -a --dry-run --target-zone 'my-sample-private-hosted-zone\.internal' # dry-run
$ bundle exec roadwork -a --target-zone 'my-sample-private-hosted-zone\.internal'

EC2 の tag.Name の値で対象サーバにアクセスできることを確認

数分待ってから DNS が引けることを確認
(↓は roadworker 用 EC2 インスタンスの tag.Name を roadworker-exec-server としていた場合)

$ roadworker-exec-server.my-sample-private-hosted-zone.internal | grep -A 1 'ANSWER SECTION'
;; ANSWER SECTION:
roadworker-exec-server.my-sample-private-hosted-zone.internal. 55 IN A 10.0.0.60
$ ssh roadworker-exec-server
Last login: Thu Dec 14 00:00:00 2017 from XXX.XXX.XXX.XXX

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2017.09-release-notes/
[ec2-user@ip-10-0-0-60 ~]$

ssh できるところまで確認できたので、あとは roadwork を cron とかで定期的にで実行するようにしておけばインスタンスが追加されても tag.Name を使って ssh とかできるようになりそうです

注意点としては今回作成した Routefile だと tag.Name が重複する場合は IP が上書きされたりと行ったことがあるので tag.Name で ssh したいインスタンスの tag.Name は重複しないようにする必要があります

感想

環境構築で微妙にハマるところがあったけれど Codenize.tools(roadworker) 便利でした

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0