DNSの設定を自動化しよう！😁💫

:space_invader: [IDCFクラウドDNS](http://www.idcf.jp/cloud/dns/)のPR記事です
# はじめに :grin: 
こんにちは。IDCフロンティア UX開発部の原田梨沙です。
7月よりUX開発部に配属になりRubyの勉強をしています！

この記事では、IDCFクラウドDNS APIのRuby用クライアントの利用方法について説明します。

たくさんのゾーンやレコードの設定を、1つ1つ手動でやるのはとても大変ではないでしょうか :worried: 
そのような大変な作業もAPIを使うことで解決できます！
IDCFクラウドDNSでは[API](http://docs.idcf.jp/cloud/dns/)が公開されています。また、Ruby用のAPIクライアント[idcf-dns-ruby](https://github.com/idcf/idcf-dns-ruby)がオープンソースとして公開されています。idcf-dns-rubyを使うことで簡単にDNSの設定を自動化することができます！ :tada:

この記事はLinuxやプログラムの基礎知識がある方向けに書いています。
Rubyが専門ではない方にもある程度理解できるように書きましたので、ぜひ最後までお付き合いください :blush: 

# IDCFクラウド DNS :pager: 
IDCFクラウド DNSは、IDCフロンティアが提供するクラウド型DNSサービスです。DNSサーバーをクラウドで管理できるので、サーバーの構築や維持管理の手間がありません。詳しくは[サービス紹介ページ](https://www.idcf.jp/cloud/dns/)をご覧ください。
APIも提供されています。詳しくは[API リファレンス](http://docs.idcf.jp/cloud/dns/)を参照してください。

APIを使うことでDNSの設定を自動化することができます。
一般的に自動化のメリットとしては、作業ミスの防止や作業時間の短縮などがあります。
特にDNSの場合は1つの設定ミスがサービス全断の原因にもなるため、ミスは許されません。作業時間の観点で言えば、大量のゾーンやレコードを管理している場合、Webコンソールの画面で1つずつ設定変更をする必要がなくなり作業時間の短縮になります。また、アカウント毎にドメイン名を割り振るようなウェブサービスでは、APIを使えば簡単にドメイン設定をアプリケーションに組み込むことができます。

## idcf-dns-rubyとは
idcf-dns-rubyはRubygemsとして公開されているIDCFクラウドDNS APIのRuby用クライアントです。
Rubygems名は[idcf-dns](https://rubygems.org/gems/idcf-dns)です。
他の言語でももちろんAPIを使うことはできますが、今提供されているのはこのRuby版のみです。

# 事前準備 :wrench: 
## bundlerでgemのインストール
idcf-dns-rubyを使うための準備をしていきましょう。

はじめに、bundlerというgemを使ってgemのインストールを行います。
bundlerはgemのパッケージとバージョンを一括管理することができるgemです。bundlerを使うことで依存関係のあるgemの管理がしやすくなります。今回はbundlerの詳しい説明は省きます。

`gem install`コマンドでbundlerをインストールします。
`$ gem install bundler`

作業用のディレクトリを用意してそのディレクトリに移動しましょう。

```
$ mkdir idcf-dns-ruby-test
$ cd idcf-dns-ruby-test
```

gemを一括管理するための`Gemfile`ファイルを作成します。
`$ bundle init`
`Gemfile`にインストールしたいgem名を次のように書き込みます。

```rb:Gemfile
gem "idcf-dns"
gem "dotenv"
```
idcf-dnsはidcf-dns-rubyのgem名です。
dotenvは次の項で説明するgemです。ついでにここでインストールしましょう。

`Gemfile`に書き込めたら、`bundle install`コマンドでgemをインストールします。

```
$ bundle install
```

<img width="521" alt="スクリーンショット 2015-12-02 10.57.48.png (134.0 kB)" src="https://img.esa.io/uploads/production/attachments/2057/2015/12/02/5683/6ac7a140-3b8d-4423-ab2f-2133ec1fe02e.png">

idcf-dnsとdotenvがインストールされました。:tada:

## dotenvでAPI keyとSecret keyの管理
dotenvというgemを使って、API keyとSecret keyを環境変数に設定します。
dotenvはアプリケーションで使う環境変数を`.env`というファイルで管理することができるようになるgemです。
カレントディレクトリの`.env`に環境変数を設定しておくと自動で`ENV`にその値を追加してくれます。今回はAPI keyとSecret keyの値を環境変数に設定しましょう。

まず、API keyとSecret keyの値を取得します。
IDCFクラウドのコンソール画面の[アカウント設定]から[API Key]をクリックします。ページ内に表示されているAPI KeyとSecret Keyを使います。
![IDCFクラウド 3.png (99.2 kB)](https://img.esa.io/uploads/production/attachments/2057/2015/11/19/5683/f9c12f5f-27fb-4cfd-8957-4507ac0fcc10.png)

次に、`.env`というファイルを作ります。このファイル内で環境変数を定義します。
以後説明で使用するキーはダミーのキーです。実際にはご自分のAPI keyとSecret keyをいれてください。

```bash:.env
IDCF_API_KEY="81cee7430542c84e6c8d5f4ba8fd00ae43e26c4fc460d42e410481a2713f"
IDCF_SECRET_KEY="94dd39d0bbe3eceaa2b6746a35dba7c0f1354a30019451c6a5ceef6c08b3"
```

プログラムの中で環境変数を参照するには、`ENV["IDCF_API_KEY"]`, `ENV["IDCF_SECRET_KEY"]` のように記述します。

```dotenv.rb
require "dotenv"
Dotenv.load

ENV["IDCF_API_KEY"] #=> "81cee7430542c84e6c8d5f4ba8fd00ae43e26c4fc460d42e410481a2713f"
ENV["IDCF_SECRET_KEY"] #=> "94dd39d0bbe3eceaa2b6746a35dba7c0f1354a30019451c6a5ceef6c08b3"
```
`Dotenv.load`メソッドはカレントディレクトリの.envファイルを読みこみ、`ENV["IDCF_API_KEY"]`, `ENV["IDCF_SECRET_KEY"]` に呼び出します。

これでAPI keyとSecret keyの設定は終了です。
 
今回、API keyとSecret keyを環境変数に設定しました。
API key や Secret keyはユーザの認証にかかわる大事な情報です。今回の例にかかわらず、プログラム自体のソースコードとは分けて管理するのがおすすめです。理由としては、

- 本番環境では環境変数をOS側に埋め込み、開発環境では値をファイルで管理できること
- CIも認証情報を環境変数で管理することが多いので、この形にそっておくとCIを導入しやすいこと

などが挙げられます。

# idcf-dns-rubyを使ってみよう :wink: 
GemのインストールとAPI Key・Secret keyの設定が終わり、idcf-dns-rubyを使うための準備が整いました。
いよいよ！idcf-dns-rubyを使ってみましょう！:grin: :tada: 

## クライアントの生成
リクエストを送るためにIdcf::Dns::Clientクラスのインスタンスを生成します。Clientのメソッドは基本的にResponseクラスのインスタンスを返します。
インスタンスの生成にはAPI keyとSecret keyが必要となります。dotenvで設定されている環境変数を使ってクライアントを生成してみましょう。

```client.rb
require "idcf/dns"
require "dotenv"

Dotenv.load

client = 
  Idcf::Dns::Client.new(
    api_key: ENV["IDCF_API_KEY"], 
    secret_key: ENV["IDCF_SECRET_KEY"] 
  )
```

正しく設定されているか、ゾーン情報を取得するGETリクエストを送信して確認してみましょう。

```client.rb
response = client.get("zones")
response.success? #=> true
response.status #=> 200
```

Response#statusでHTTPレスポンスのステータスコードを確認できます。
（クラス名#メソッド名はあるクラスのインスタンスメソッドを表す表記方法です。この場合はResponseクラスのインスタントメソッドであるstatusを表しています。）
HTTPステータスコード が"200"なので、クライアントがちゃんと動いていることを確認できました。:grin:
次項から、idcf-dns-rubyの具体的な使い方をみていきます。

## ゾーン、レコードの一覧取得
Client#list_zonesでゾーン一覧を取得しましょう。
Response#bodyでレスポンスの内容を取得できます。
 レスポンスにはゾーンのUUID、ドメイン名、ゾーンの作成日時などの情報が含まれています。

```list_zones.rb
response =
  client.list_zones

response.body #=>
[{"uuid"=>"283a5e3f-7597-4902-8b6a-f6751de60918",
  "name"=>"foobar.example.com",
  "default_ttl"=>3600,
  "created_at"=>"2015-11-09T13:24:58+09:00",
  "updated_at"=>"2015-11-20T17:41:11+09:00",
  "description"=>"Hello!",
  "authenticated"=>false},
 {"uuid"=>"c0ea3811-b7d4-4e3f-b2e8-bc65cd18d49c",
  "name"=>"foo.example.com",
  "default_ttl"=>3600,
  "created_at"=>"2015-11-09T13:28:38+09:00",
  "updated_at"=>"2015-11-09T15:09:49+09:00",
  "description"=>"DNSのRubyクライアントテスト用!",
  "authenticated"=>true},
 {"uuid"=>"7386f8f8-df54-4887-9e96-2f3ea624bcc5",
  "name"=>"foobarfoo.example.com",
  "default_ttl"=>600,
  "created_at"=>"2015-11-10T09:26:04+09:00",
  "updated_at"=>nil,
  "description"=>"",
  "authenticated"=>false}]
```

Response#countでゾーン数を取得できます。

```count.rb
response = client.list_zones
response.count #=> 3
```

Client#list_recordsでレコード一覧を取得しましょう。
Response#bodyでレスポンスの内容を取得できます。
レスポンスにはSOAレコード、NSレコード、レコードのUUIDなどの情報が含まれています。

```list_records.rb
response =
  client.list_records("ddcd8dbf-8d99-4f49-9958-7dd9a0bfb67f") # ゾーンのUUID

response.body #=>
  [{"uuid"=>"9fae4a12-319c-4afc-ac33-4542ef79dd0b",
    "name"=>"foobar.example.com",
    "type"=>"SOA",
    "content"=>
     {"dns"=>"ns01.idcfcloud.com",
      "email"=>"foobar.example.com.",
      "serial"=>4,
      "refresh"=>10800,
      "retry"=>3600,
      "expire"=>604800,
      "ttl"=>3600},
    "ttl"=>3600,
    "created_at"=>"2015-11-09T13:24:58+09:00",
    "updated_at"=>"2015-11-09T16:07:21+09:00",
    "priority"=>nil},
   {"uuid"=>"f61a75b7-8e9c-4e69-a91a-6e6aa90c2990",
    "name"=>"foobar.example.com",
    "type"=>"NS",
    "content"=>"ns01.idcfcloud.com",
    "ttl"=>3600,
    "created_at"=>"2015-11-09T13:24:58+09:00",
    "updated_at"=>nil,
    "priority"=>nil},
   {"uuid"=>"0195fe5d-7cff-4f94-8886-a13bb0f609b4",
    "name"=>"foobar.example.com",
    "type"=>"NS",
    "content"=>"ns02.idcfcloud.com",
    "ttl"=>3600,
    "created_at"=>"2015-11-09T13:24:58+09:00",
    "updated_at"=>nil,
    "priority"=>nil},
   {"uuid"=>"0bdc7d49-b1aa-4455-903f-35dc3c4338be",
    "name"=>"foobar.example.com",
    "type"=>"NS",
    "content"=>"ns03.idcfcloud.com",
    "ttl"=>3600,
    "created_at"=>"2015-11-09T13:24:58+09:00",
    "updated_at"=>nil,
    "priority"=>nil},
   {"uuid"=>"ecacc77f-e678-4f29-b6dd-6bec79c172a1",
    "name"=>"www.foobar.example.com",
    "type"=>"A",
    "content"=>"8.8.8.8",
    "ttl"=>3600,
    "created_at"=>"2015-11-09T16:07:21+09:00",
    "updated_at"=>nil,
    "priority"=>nil}]
```

Response#countでレコード数を確認できます。

```count.rb
response =
  client.list_records("ddcd8dbf-8d99-4f49-9958-7dd9a0bfb67f") 

response.count #=> 5
```

## ゾーンの作成、更新、削除
Client#create_zoneでゾーンを新規作成します。
 詳細なリクエストパラメータは[ドキュメント](http://www.rubydoc.info/gems/idcf-dns/Idcf/Dns/ClientExtensions/Zone#create_zone-instance_method)を 参照してください。 
Response#uuidで新規作成したゾーンのUUIDを確認できます。

 ```create_zone.rb
response =
  client.create_zone(
    name: "foobar.example.com",
    email: "foobar@example.com",
    description: "",
    default_ttl: 600
  )

response.uuid #=> "384178f5-58a5-4f3c-9607-5e189ab2990d"
```

Client#update_zoneでゾーン情報を更新します。
詳細なリクエストパラメータは[ドキュメント](http://www.rubydoc.info/gems/idcf-dns/Idcf/Dns/ClientExtensions/Zone#update_zone-instance_method)を 参照してください。


```rb
response =
  client.update_zone(
    "384178f5-58a5-4f3c-9607-5e189ab2990d", # 更新するゾーンのUUID
    description: "Change description",
    default_ttl: 3600
  )
```

Client#delete_zoneでゾーンを削除します。

```delete.rb
response =
  client.delete_zone("83f55e72-e3fa-4961-89b3-99ee43617b93") # 削除したいゾーンのUUID

response.body #=> {}

response.status #=> 200
```

## レコードの作成、更新、削除
Client#create_recordでレコードを新規作成します。
詳細なリクエストパラメータは[ドキュメント](http://www.rubydoc.info/gems/idcf-dns/Idcf/Dns/ClientExtensions/Record#create_record-instance_method)を 参照してください。

```create_record.rb
response =
  client.create_record(
    "ddcd8dbf-8d99-4f49-9958-7dd9a0bfb67f", # レコードを追加するゾーンのUUID
    name: "www.foobar.example.com",
    type: "A",
    content: "8.8.8.8",
    ttl: 3600
  )

response.uuid #=> "40d5f26f-02bd-4fb1-b363-323675772289"
```

Client#update_recordでレコードを更新します。
詳細なリクエストパラメータは[ドキュメント](http://www.rubydoc.info/gems/idcf-dns/Idcf/Dns/ClientExtensions/Record#update_record-instance_method)を 参照してください。

```update_record.rb
response =
  client.update_record(
    "ddcd8dbf-8d99-4f49-9958-7dd9a0bfb67f", # 更新するレコードの属するゾーンのUUID
    "d612aabb-3fea-471a-8712-586f1ac9c29c", # 更新するレコードのUUID
    content: "6.6.6.6"
  )
```

Client#delete_recordでレコードを削除します。

```delete_record.rb
response =
  client.delete_record(
    "ddcd8dbf-8d99-4f49-9958-7dd9a0bfb67f", # 削除したいレコードの属するゾーンUUID
    "d612aabb-3fea-471a-8712-586f1ac9c29c" # 削除したいレコードのUUID
  )

response.body #=> {}
response.status #=> 200
```

idcf-dns-rubyの使い方の説明は以上です。

#  バグ報告、質問、改善要望 :bug:

バグ報告、質問、 改善要望などがありましたら、[GithubのIssue](https://github.com/idcf/idcf-dns-ruby/issues)でお知らせください。
なぜか英語ばかりですが、もちろん日本語でも大丈夫です :grin: :jp: 
Pull Requestは大大大歓迎です！
お待ちしております :blush: 

# おわりに :pray: 
idcf-dns-rubyを使ってゾーンやレコードを設定する方法について説明しました。
作業効率化やサービス開発のお役に立てれば幸いです。

そして！

IDCフロンティア UX開発部 ではソフトウェアエンジニアを募集中です :relaxed: 
自社サービスの開発に興味のある方はぜひご応募ください :raised_hands: