PHP
AWS
dns
SDK
route53

AWS SDK for php でRoute53を操作する

やりたいこと

AWS Route53 を aws sdk を用いて php で操作したい。

前提条件

・管理ポリシー
 作成したユーザーの管理ポリシーは以下のようなポリシーをアタッチしておく
- AmazonRoute53DomainsFullAccess
- AmazonRoute53FullAccess

1. phpで AWS CLIのアクセスする準備

セットアップ手順はいくつかありますが、ここではComposerを利用した手順でサクッと準備します。

1-1. Composer のインストール

# curl -sS https://getcomposer.org/installer | php

1-2. 最新版のSDK導入

# php composer.phar require aws/aws-sdk-php

1-3. Composer’s autoloaderの読み込み

実際にphpでSDKを参照するにはautoload.phpを読み込む。

<?php
require ‘vendor/autoload.php’;

2. スクリプトの準備

以下の構成でスクリプトを準備します。

+config.php 設定ファイル(環境によってkey,secret等を設定する。)
+DNSUtil.php Route53制御用のクラス
+test.php テスト呼び出しファイル

2-1. config.php

<?php

class AWSConfig {

// AWS - credentials
  public static $Credential_Key    = "xxxxxxxxxxxxxxxxxxxx";
  public static $Credential_Secret = "****************************************";
  public static $Region = "ap-northeast-1";

// AWS - Route53
  public static $Route53_HostedZoneId = "...";

}

2-2. DNSUtil.php

<?php
/**
 * Route53 を制御してDNSの管理を行います。
 *
 */
require_once (dirname(__FILE__) . '/config.php');
require '/<path to aws-sdk>/vendor/autoload.php';
use Aws\Route53\Route53Client;

class DNSUtil {
   /**
    * コンストラクタ
    *
    */
    function __construct() {
        $this->client = Route53Client::factory(array(
            'version'     => 'latest',
            'credentials' => array(
                'key'     => AWSConfig::$Credential_Key,
                'secret'  => AWSConfig::$Credential_Secret,
            ),
            'region' => AWSConfig::$Region,
        ));
    }

   /**
    * レコード一覧取得
    * ここではレコードタイプを指定して一覧取得しています。
    *
    */
    public function getList($type="A") {
        $ret = array();
        try {
            // http://docs.aws.amazon.com/aws-sdk-php/v2/api/class-Aws.Route53.Route53Client.html#_listResourceRecordSets
            $res = $this->client->listResourceRecordSets(array(
                'HostedZoneId' => AWSConfig::$Route53_HostedZoneId,
            ));
            foreach ($res['ResourceRecordSets'] as $record) {
                $res_type = $record['Type'];
                if ($res_type != $type) {
                    continue;
                }
                $name = $record['Name'];
                $val  = $record['ResourceRecords'][0]['Value'];
                $ret[$name] = $val;
            }
        } catch (Exception $e) {
            // http://docs.aws.amazon.com/aws-sdk-php/v2/api/namespace-Aws.Route53.Exception.html
            echo $e->getMessage();
        }
        return $ret;
    }

   // Aレコードの更新 なければ作成、あれば更新
    public function update_ARecord($domain, $address) {
        // http://docs.aws.amazon.com/aws-sdk-php/v2/api/class-Aws.Route53.Route53Client.html#_changeResourceRecordSets
        $arrays = array(
            'Action' => 'UPSERT',  // string: CREATE | DELETE | UPSERT
            'ResourceRecordSet' => array(
                'Name' => $domain,
                'Type' => 'A',
                'TTL'  => 86400,
                'ResourceRecords' => array(
                    array(
                        'Value' => $address,
                    ),
                ),
            ),
        );
        try {
            $this->client->changeResourceRecordSets(array(
                'HostedZoneId' => AWSConfig::$Route53_HostedZoneId,
                'ChangeBatch'  => array(
                    'Comment' => 'from my PHP script',
                    'Changes' => array($arrays),
                ),
            ));
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }

    // Aレコード削除
    public function delete_ARecord($domain, $address) {
        $arrays = array(
            'Action' => 'DELETE',  // string: CREATE | DELETE | UPSERT
            'ResourceRecordSet' => array(
                'Name' => $domain,
                'Type' => 'A',
                'TTL'  => 86400,
                'ResourceRecords' => array(
                    array(
                        'Value' => $address,
                    ),
                ),
            ),
        );
        try {
            $this->client->changeResourceRecordSets(array(
                'HostedZoneId' => AWSConfig::$Route53_HostedZoneId,
                'ChangeBatch'  => array(
                    'Comment' => 'from my PHP script',
                    'Changes' => array($arrays),
                ),
            ));
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }

}

Route53Clientのインスタンスを生成します。
レコードの更新APIでは、レコードの作成、削除、更新が「CREATE」「DELETE」「UPSERT」
で指定できます。

2-3. test.php

<?php
require_once (dirname(__FILE__) . '/DNSUtil.php');

$obj = new DNSUtil();
// Aレコードの更新・設定
$obj->update_ARecord('hoge1.test.net', '11.22.33.44');
//$obj->delete_ARecord('hoge1.test.net', '11.22.33.44');

// Aレコードの一覧取得
$list = $obj->getList("A");
foreach ($list as $domain => $address) {
    print("domain : $domain -> address:$address \n");
}

動作確認

以下のように呼び出してエラーなく、情報が更新、取得できることを確認できる。

# php test.php

参考文献

AWS SDK for PHP ; Installing using Composer
http://docs.aws.amazon.com/aws-sdk-php/v2/guide/installation.html#installing-using-composer

listResourceRecordSets:一覧取得
http://docs.aws.amazon.com/aws-sdk-php/v2/api/class-Aws.Route53.Route53Client.html#_listResourceRecordSets

changeResourceRecordSets:レコード値の更新
http://docs.aws.amazon.com/aws-sdk-php/v2/api/class-Aws.Route53.Route53Client.html#_changeResourceRecordSets