概要
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.tools の roadworker を使って 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) 便利でした