モチベーション

すでにTokyoリージョンでRDSを運用していて、Virginiaリージョンで新しくRDSを立てるときTokyoリージョンにあるParameter Groupと同じ設定のものをVirginiaリージョンで使いたかった。はじめは、copy-db-parameter-groupを使ってParameter Groupをクロスリージョンでコピーしようとしたがどうやらできないようなので、describe-db-parametersを使って力技で解決した。今後も同じことをする可能性が高いのでメモを残しておく。

copy-db-parameter-groupを使ってみた

copy-db-parameter-group AWS CLI 1.10.47 Command Referenceをみると、ARNを指定すればクロスリージョンでParameter Groupをコピーできるようなことが書かれているのでやってみた。

# 同一リージョンの場合
> aws rds copy-db-parameter-group \
--region us-east-1 --source-db-parameter-group-identifier source-pg \
--target-db-parameter-group-identifier dest-pg \
--target-db-parameter-group-description  'copy test'

{
    "DBParameterGroup": {
        "DBParameterGroupName": "dest-pg",
        "DBParameterGroupFamily": "mysql5.6",
        "Description": "copy test"
    }
}

同一リージョンで名前指定で実行するとコピーができた。一方で、リージョンをまたいでARN指定でコピーをすると以下のようなエラーが発生してコピーできない。

# クロスリージョンの場合
> aws rds copy-db-parameter-group \
--region ap-northeast-1 --source-db-parameter-group-identifier arn:aws:rds:us-east-1:<your_acccount_id>:pg:source-pg \
--target-db-parameter-group-identifier dest-pg \
--target-db-parameter-group-description  'copy test'

A client error (DBParameterGroupNotFound) occurred when calling the CopyDBParameterGroup operation: DB ParameterGroup not found, not allowed to do cross region copy.

ドキュメントを読むとクロスリージョンでもコピーできるようなこと書かれているのだが、Stack overflowをみると同じようことでハマっている人がいて、どうやらドキュメントには書かれているが機能としては備わっていない状態とのこと。

I ran into this same issue recently and opened a support ticket with AWS. The response I got was that the RDS team added this feature to the documentation but haven’t yet built the actual support for this feature.

無いものは書かないで欲しい。

TokyoリージョンのPGをjsonに落としこむ

しかたがないので、describe-db-parametersmodify-db-parameter-group経由で力技でコピーする。具体的には以下のコマンドを使ってTokyoリージョンのPG情報をひとまずsonに書きだした。

> aws rds describe-db-parameters --db-parameter-group-name tokyo_source_pg --region ap-northeast-1 > tokyo_source_pg.json

書きだしたjsonは以下のようになる。

{
    "Parameters": [
        {
            "ApplyMethod": "pending-reboot",
            "Description": "Controls whether user-defined functions that have only an xxx symbol for the main function can be loaded",
            "DataType": "boolean",
            "AllowedValues": "0,1",
            "Source": "engine-default",
            "IsModifiable": false,
            "ParameterName": "allow-suspicious-udfs",
            "ApplyType": "static"
        },
        {
            "ApplyMethod": "pending-reboot",
            "Description": "Intended for use with master-to-master replication, and can be used to control the operation of AUTO_INCREMENT columns",
            "DataType": "integer",
            "AllowedValues": "1-65535",
            "Source": "engine-default",
            "IsModifiable": true,
            "ParameterName": "auto_increment_increment",
            "ApplyType": "dynamic"
        },
        {
            "ApplyMethod": "pending-reboot",
            "Description": "Determines the starting point for the AUTO_INCREMENT column value",
            "DataType": "integer",
            "AllowedValues": "1-65535",
            "Source": "engine-default",
            "IsModifiable": true,
            "ParameterName": "auto_increment_offset",

また、書きだしたjsonからcatで全てのパラメータの中からユーザがデフォルトから変更したものを抽出する。ApplyMehodをpending-rebootからimmediateにしているのはApplyTypeがdynamicのもパラメータを即時反映させるため。(immediateはApplyTypeがstaticの時は使えない)

> cat tokyo_source_pg.json | jq '{Parameters:[ (.Parameters[]|select(.Source == "user") * {"ApplyMethod":"immediate"})]}' | cat > virginia_dest_pg.json

適用後のjsonはこんな感じ。

{
  "Parameters": [
    {
      "ApplyMethod": "immediate",
      "Description": "Row or Mixed replication",
      "DataType": "string",
      "IsModifiable": true,
      "AllowedValues": "ROW,MIXED",
      "Source": "user",
      "ParameterValue": "ROW",
      "ParameterName": "binlog_format",
      "ApplyType": "dynamic"
    },
    {
      "ApplyMethod": "immediate",
      "Description": "The character set for statements that arrive from the client.",
      "DataType": "string",
      "IsModifiable": true,
      "AllowedValues": "big5,dec8,cp850,hp8,koi8r,latin1,latin2,swe7,ascii,ujis,sjis,hebrew,tis620,euckr,koi8u,gb2312,greek,cp1250,gbk,latin5,armscii8,utf8,cp866,keybcs2,macce,macroman,cp852,latin7,utf8mb4,cp1251,cp1256,cp1257,binary,geostd8,cp932,eucjpms",
      "Source": "user",
      "ParameterValue": "utf8mb4",
      "ParameterName": "character_set_client",
      "ApplyType": "dynamic"
    },

最後に、modify-db-parameter-groupでパラメータを更新するのだが、Virginiaリージョンで先にというvirginia_pgという名前のPGを作っておき、以下を実行する。

> aws rds modify-db-parameter-group --db-parameter-group-name virginia_pg --cli-input-json file://virginia_dest_pg.json  --region us-east-1

file://をつけないとエラーが発生するのでつける(jsonがdecodeうんちゃらみたいなやつ)ので注意。PGの変更が正常に終了すればこのような出力が返ってくる。

{
    "DBParameterGroupName": "virginia_pg"
}

参考