20200320のAWSに関する記事は11件です。

AppSyncでLambdaを呼び出す

AppSyncでLambdaを呼び出す

はじめに

先日「API Gatewayでリクエストして、Lambdaで処理させて、AppSyncで受け取る」という記事を書きました。この記事のあとがきにも書いたのですが、フロントエンドからLambdaを実行させるために何の迷いもなくAPI Gatewayを利用していたのですが、どうやらAppSyncでも出来そうだぞということで。

データソースにDynamoDBを指定しているAppSyncへ、LambdaをデータソースとするIFを追加します。

スキーマへIFの追加

AppSyncのスキーマに、モザイク処理を実行するためのIFを追加します。
AWSコンソール > AppSync > 目的のAPI > スキーマ
MutationへprocessApplyMosaicという関数、そして入出力用のデータ型を定義します。
入出力用のデータ型はAPI Gatewayの時と同じ仕様とし、また、認証タイプはCognitoとします。

 :
input ProcessApplyMosaicInput {
    guid: String!
    orgKey: String!
    pointsList: [String]
}

type ProcessApplyMosaicResult @aws_cognito_user_pools {
    statusCode: Int!
    body: String
}

type Mutation {
    processApplyMosaic(input: ProcessApplyMosaicInput!): ProcessApplyMosaicResult
        @aws_cognito_user_pools
    createSampleAppsyncTable(input: CreateSampleAppsyncTableInput!): SampleAppsyncTable
        @aws_iam
 :

スキーマを保存ボタンを押下してください。

リゾルバーの追加

スキーマを編集して保存すると、スキーマの右側にあるResolversというところに追加したprocessApplyMosaicが表示されるようになります。Resolverはまだ未割り当てなので「アタッチ」ボタンを押下して割り当てることになります。
Screenshot 2020-03-21 at 00.01.21.png
が、一時中断です。その前にやることがあります。

Lambdaの作成

スキーマのMutationに追加したprocessApplyMosaicのリゾルバーを割り当てるためのLambdaを作成します。

AWSコンソール > Lambda > 関数の作成 > 一から作成
名前は「apply_mosaic_from_appsync」、ラインタイムは「Python 3.6」として作成します。

作成したLambdaのIAMロールに必要な権限を当てておきます。
AWSコンソール > IAM > ロール > Lambdaとセットで作成されたロール(apply_mosaic_from_appsync-role-xxxxxxxx)
S3とAppSyncへのアクセスが必要ですので、以下のような内容でインラインポリシーを追加します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "appsync:GraphQL"
            ],
            "Resource": [
                "arn:aws:s3:::sample-vue-project-bucket-work/*",
                "arn:aws:appsync:ap-northeast-1:888888888888:apis/xxxxxxxxxxxxxxxxxxxxxxxxxx/*"
            ],
            "Effect": "Allow"
        }
    ]
}

作成したLambdaに この記事 で作成したPythonコードをインポートするわけですが、インプットパラメータを受け取るところの実装を少しだけ変更します。

 :
def lambda_handler(event, context):
    try:
        # guid = event["guid"]
        # orgKey = event["orgKey"]
        # pointsList = event["pointsList"]
        # AppSyncから渡される引数はinputタグの中に入れてるので↓のように変更する。
        guid = event["input"]["guid"]
        orgKey = event["input"]["orgKey"]
        pointsList = event["input"]["pointsList"]
 :

データソースの作成

AWSコンソール > AppSync > 目的のAPI > データソース
データソースの作成ボタンを押下し、先ほど作成したLambdaを選択して作成します。
Screenshot 2020-03-19 at 00.03.52.png

リゾルバーへLambdaのアタッチ

それでは中断した作業に戻ります。
AppSyncのスキーマの右側にあるResolversというところに追加したprocessApplyMosaicが表示されるようになり、そこに表示されている「アタッチ」ボタンを押下します。
データソース名のコンボボックスから先ほど作成したデータソースを選択して、「リゾルバーを保存」ボタンを押下します。リクエスト/レスポンス マッピングテンプレートは特に編集しません。Screenshot 2020-03-19 at 00.06.00.png

これでAPI側の準備は整いました。

フロントエンドから呼び出し

それではフロントエンドから呼び出してみましょう。
VueのWebアプリにてAPI Gatewayで呼び出していたところをAppSyncに置き換えることになります。

src/graphql/mutations.js
export const processApplyMosaic = `
    mutation processApplyMosaic($input: ProcessApplyMosaicInput!) {
        processApplyMosaic(input: $input) {
            statusCode
            body
        }
    }
`;
src/components/List.vue
 : 
<script>
import { Auth, API, graphqlOperation, Storage } from 'aws-amplify';
import { listSampleAppsyncTables } from "../graphql/queries";
import { onCreateSampleAppsyncTable } from "../graphql/subscriptions";
import { processApplyMosaic } from "../graphql/mutations";
 :
    async processMosaic() {
       :       
      /* API Gatewayの時のコード
      const currSession = await Auth.currentSession();
      config.headers["Authorization"] = currSession.getIdToken().getJwtToken();
      axios
      .post(apiUrl, {guid: this.myGuid, orgKey: orgKey, pointsList: pointsList}, config)
      .then(response => {
          let result = response.data
          console.log(result)
      }).catch(error => console.log(error))*/

      let apiResult = await API.graphql(graphqlOperation(processApplyMosaic, 
        {input : {guid: this.myGuid, orgKey: orgKey, pointsList: pointsList}})
      ).catch(error => {
        console.error(error);
      });
    }, 
 :

コード的にも、Amplifyで統一できてスッキリしましたね。

あとがき

AppSyncとAPI Gateway、両方使うことで得られるメリットはアーキテクチャ図のアイコンが増えて華やかになることくらいでしょうか。
というのは流石に冗談が過ぎますね。

目的を実現するための手段は多岐にわたりますが、より多くの選択肢の中から適切に取捨選択できるようになりたいものです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】CloudFront+S3で署名付きURLを使いプライベートコンテンツを配信する

環境

  • PHP 7.4.1
  • Composer 1.9.3
  • Laravel Framework 6.14.0
  • league/flysystem-aws-s3-v3 1.0.24
  • aws/aws-sdk-php 3.133.40
  • aws/aws-sdk-php-laravel 3.5.0

手順

長いのでだいぶ雑です。

1. S3アップロード実装

まず公式ドキュメントに則り、Flysystemを使ってS3に画像をアップロードするところまで進めます。
AWSアカウントの作成, S3バケットの作成, IAMポリシー/ユーザの作成などは、ググれば良い資料が沢山出てくるのでそちらを参照してください。

composer require league/flysystem-aws-s3-v3

config/filesystems.phpには既にS3用の記述が存在するため、編集する必要はありません。
.envファイルは自身の環境に合わせて書き換えましょう。

config/filesystems.php(編集不要)
        's3' => [
            'driver' => 's3',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION'),
            'bucket' => env('AWS_BUCKET'),
            'url' => env('AWS_URL'),
        ],
/.env
AWS_ACCESS_KEY_ID=hoge
AWS_SECRET_ACCESS_KEY=fuga
AWS_DEFAULT_REGION=ap-northeast-1
AWS_BUCKET=hoga
AWS_URL=

画像アップロード用のHTMLとコントローラ、ルーティングを作成します。

routes/web.php
Route::get('/', function () {
    return view('index');
});
Route::Post('/', 'TestController@create');
resources/views/index.blade.php
<form method="POST" action="/" enctype="multipart/form-data">
    {{ csrf_field() }}
    <input type="file" name="media" accept="image/*">
    <input type="submit">
</form>
app/Http/Controllers/TestController.php
use Illuminate\Http\Request;
use Storage;

    public function create(Request $request) {
        // S3アップロード
        $media = $request->file('media');
        $path = Storage::disk('s3')->putFile('/', $media);
        $url = Storage::disk('s3')->url($path);
        dd($url);
    }

アップロードがうまくいかない場合、IAMポリシーやアクセスキーのチェックを行い、php artisan cache:clearphp artisan config:clearを叩いてみましょう。

この状態では、URLを叩くとエラーになるはずです。画像をブラウザで確認する場合、S3バケットのパブリックアクセスをオンにする必要があります。
S3バケットの「パブリックアクセスをすべてブロック」をオフにして、putFile()の第三引数に'public'を追記してアップロードすると、見れるようになるはずです。確認が終わったら設定を戻しておきましょう。

2. CloudFrontとの連携

ルートユーザでAWSマネジメントコンソールにアクセスし、「マイセキュリティ資格情報」からCloudFrontキーペアを生成します。
キーペアをダウンロードし、秘密鍵をアプリケーションディレクトリ直下に保存します。

/pk-hogefuga.pem
-----BEGIN RSA PRIVATE KEY-----
aaaaaaaaaaaaa
-----END RSA PRIVATE KEY-----

次に、CloudFrontのページで「Create Distribution」→Webの「Get Started」と進み、以下の情報を入力して設定を完了します。StatusがDeployedに変わるまで待ちましょう。
この操作が完了すると、S3のバケットポリシーが更新され、CloudFront経由でしかアクセスできないようになります。

Origin Domain Name: S3のバケットを選択
Restrict Bucket Access: Yes
Origin Access Identity: Create a New Identity
Grant Read Permissions on Bucket: Yes, Update Bucket Policy
Restrict Viewer Access(Use Signed URLs or Signed Cookies): Yes
Trusted Signers: Self

次に、以下のコマンドでAWS SDKを導入します。
コマンド入力後は、 https://github.com/aws/aws-sdk-php-laravel に記載のある通り、providersとaliasesを更新します。
その後、composer dump-autoloadを叩いてください。

composer require aws/aws-sdk-php-laravel

ここまでできたら、後は署名付きURLを取得するだけです。
コントローラと.envファイルを以下のように書き換えます。

app/Http/Controllers/TestController.php
use Illuminate\Http\Request;
use Storage;
use AWS;

    public function create(Request $request) {
        // S3アップロード
        $media = $request->file('media');
        $path = Storage::disk('s3')->putFile('/', $media);
        $url = Storage::disk('s3')->url($path);

        // 署名付きURLを取得
        $client = AWS::createClient('cloudfront');
        $signedUrlCannedPolicy = $client->getSignedUrl([
            'url' => $url,
            'expires' => time() + 30, // 30秒間有効
            'private_key' => base_path('pk-hogefuga.pem'),
            'key_pair_id' => env('AWS_CLOUDFRONT_KEY_PAIR_ID')
        ]);
        dd($signedUrlCannedPolicy);
    }
/.env
AWS_URL=https://xxx.cloudfront.net # CloudFrontのページにある「Domain Name」
AWS_CLOUDFRONT_KEY_PAIR_ID=hogefuga # 鍵ファイル名のハイフン以降の文字列

実行後、以下のようなURLが取得できたらうまくいっています。
CloudFront経由でしかアクセスできない(S3に直接アクセスが禁止されている)こと、GETパラメータを外すとアクセスできないこと、有効期限を過ぎるとアクセスできないことを確認してみてください。

https://xxx.cloudfront.net/jA7g461GuNZDqaBwI0VKAm8Ia2KjXp6E7DMTQVe8.png?Expires=1584705653&Signature=C97kAeYc3Lvr-2mJ1hKe9SSAVQJJuS0wuCmyecIXJMIES~ITw10gJkn0UE1xuMUfpwAW8Oka~dIP61FdPfshrfU4pYzHYkeqMqZzvuZjen3NwNiSqHF1h5raLuVpG9yrhnuEPJAgaMdVsKcQFG0Ej0qHMtSi9zehrPvUh-TMmeAUHhU6dBXsPHEvlPQoPzJC-sVMh2ZVgTbVgAgaTl6CK5Am3WaVsNfSjhD1jBasdC5qTLPuEFOnuVXcMBFyh2svQLtX92DDUnfAa0jx0SUQ3DAgGNuj1I-NjV4J6w30vqvlbdGBIOHTCcBveeHxohAcp4sDxwznul2bZ2IY3Rrx6Q__&Key-Pair-Id=DFNVRFXGY12IDEBGZGPL

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Elastic Beanstalkの.ebextensionsでApacheのDocument Rootを変更する方法

Elastic BeanstalkでEC2を立ち上げる際、ApacheのDocument Rootは

httpd.conf
      DocumentRoot "/var/www/html/"

となっています。
これを変更しようとしたのですが、ちょっとトリッキーなことをしたので、残しておきます。

環境

64bit Amazon Linux/2.9.3
Apache/2.4.41

やり方

.ebextensionsのフォルダ内に以下のファイルを入れます。

apache.config
files:
  /etc/httpd/conf/myhttpd.conf:
    content: |
      ##以下にDocment Rootを変更したconfファイルの内容を記載する
      ##例えば↓↓
      DocumentRoot "/var/www/html/public"

      #### End of AWS Settings ####
container_commands:
  00-rm-httpd-conf:
    command: "sudo rm /etc/httpd/conf/httpd.conf"
  01-cp-conf-file:
    command: "sudo cp /etc/httpd/conf/myhttpd.conf /etc/httpd/conf/httpd.conf"
  02-httpd-restart:
    command: "sudo httpd -k restart"

このファイルでは
①Document Rootを変更した設定ファイルmyhttpd.confをEC2に置く
②元々の設定ファイルhttpd.confでApacheを立ち上げた後、httpd.confを削除する
myhttpd.confhttpd.confに置き換える
④Apacheを再起動する
という手順を踏んでいます。

この手順を踏んでいる理由

元々は最初のApacheの立ち上げの前からhttpd.confを上書きしようとしたのですが、そうするとなぜかDocument Rootがデフォルトに書き換わってしまいました。
なので、ちょっとトリッキーな手順を踏みました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails アプリを EC2 にデプロイしよう!(サーバー構築編)

Rails アプリを Amazon Web Service を使ってデプロイするまでの手順をまとめました。
次の順番でデプロイまで持っていきます。

1, 準備編
2, サーバー構築編
3, 環境構築編
4, デプロイ編

今回は「サーバー構築編」です。
準備編」を読んでない方は先に読んでください。

EC2 インスタンスの作成

EC2とは Elastic Compute Cloud の略で、クラウド上に存在する仮想のサーバーのことです。
サーバーは、サービスを提供する (server) コンピューターのことです。
要するにパソコンを借ります。

早速借りましょう。

1, コンソール画面から検索するなりして「EC2」をクリックしてください。
2, 左のメニューバーから「インスタンス」をクリックしてください。
3, 左上辺りにある[インスタンスの作成]をクリックしてください。

AMIの選択

最初に「AMIの選択」を行います。
AMIとは Amazon Machine Image の略で、ここでは今作成しようとしているパソコン(EC2)のタイプを選択します。

4, 今回は Ruby を使用するので、
「Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type」
を選択しましょう。
Elastic Compute Cloud 2[AMI]
AMIを間違えるとRubyが動かないので注意しましょう。
OSもここで決まります。今回はAmazon Linuxを使用します。
名称が変わっている場合は、次のような説明文が書かれているものを選択してください。

Amazon Linux AMI は、AWS がサポートする EBS-backed イメージです。デフォルトのイメージには、AWS コマンドラインツール、Python、Ruby、Perl、および Java が含まれます。レポジトリには、Docker、PHP、MySQL、PostgreSQL、およびその他のパッケージが含まれます。

インスタンスタイプの選択

次に「インスタンスタイプの選択」を行います。
AWSにはさまざまな種類のCPUやメモリ、ストレージなどを組み合わせたインスタンスが存在しています。
今回は具体的なインスタンスタイプの種類について割愛します。

5, 今回は t2.micro を使用するので
次のインスタンスタイプを選択してください。
Elastic Compute Cloud 2[Instance Type]
今回は「無料枠」を選択しています。
無料枠が表示されない方もいるかもしれませんが、それについてはご了承ください。

インスタンスの詳細の設定

次は「インスタンスの詳細の設定」を行います。
いろいろ項目がありますが、意味は次の通りです。

名称 意味
インスタンス数 作成するインスタンスの数
スポットインスタンスのリクエスト 同じ地域の使用されていないインスタンスを、入札制で使用出来る仕組み。費用削減が期待できる。今回はチェックしない。
ネットワーク 使用するVPCを選択する。準備編で作成したVPCをプルダウンで選択しましょう。
サブネット 使用するサブネットを選択する。準備編で作成したサブネットをプルダウンで選択しましょう。
自動割り当てパブリックIP インターネットを通じてインスタンスにアクセスするためのIPアドレス。有効化します。
配置グループ プレイスメントグループというグループを作成することで、インスタンス間の通信速度を高速化させることができます。今回は使用しません。
キャパシティーの予約 任意の時間やタイミングでキャパシティー(性能)を上げることができます。今回は使用しません。
IAMロール IAMというユーザーの種類別にリソースの使用権限を割り振ったもの。誰がこのインスタンスにアクセス出来て、誰が出来ないかなどを設定できる。今回は設定しない。
シャットダウン動作 EC2をシャットダウンした際に削除するのか停止させるのか選択できる。
停止 - 休止動作 インスタンスの停止中に「休止状態」が選択できるようにする。
終了保護の有効化 インスタンスを誤って削除しないように設定できる。
モニタリング CloudWatchというインスタンス監視サービスを利用するかどうかを選択できる。利用すると追加料金が発生する。
テナンシー ハードウェアを占有するか、それとも他の利用者と共有するかを選択できる。
Elastic Inference 説明を割愛します。
T2/T3 無制限 説明を割愛します。

6, 今回は次のように設定します。
Elastic Compute Cloud 2[Config]

ストレージの追加

次は「ストレージの追加」を行います。
ストレージシステム(EC2)の管理に役立つ特別なディレクトリと構成ファイルが格納されている場所で、Windowsで言う所の「Cドライブ」に該当します。

7, 今回は次のように設定します。
Elastic Compute Cloud 2[Storage]

タグの追加

次は「タグの追加」を行います。
ここでEC2に名前をつけましょう。

8, 今回は次のように設定します。
Elastic Compute Cloud 2[Tag]

セキュリティグループの設定

最後に「セキュリティグループの設定」を行います。
準備編で設定したセキュリティグループを選択しましょう。

9, 今回は次のように設定します。
Elastic Compute Cloud 2[Security Group]

インスタンス作成の確認

これまでの手順を振り返って問題がなければ、
右下にある「起動」をクリックしましょう。

クリックすると「既存のキーペアを選択するか、新しいキーペアを作成します。」という画面が出てきます。

新しいキーペアの作成

SSH という通信プロトコルを使って安全な通信を行います。
この通信では、ユーザーはプライベートファイルをAWSから保存して、これを使用してインスタンスに接続します。

10, 新しいキーペアを作成して、キーペアをダウンロードしてください。
Elastic Compute Cloud 2[Key Pair]
再度ダウンロードすることはできないので注意してください。
また、安全な場所に保存するようにしてください。

これを保存した後、やっとインスタンスを作成することができます。

11, 「インスタンスの作成」をクリックしましょう。
12, 作成ステータスが表示されますが、そのまま「インスタンスの表示」をクリックしましょう。

以下のようにインスタンスが作成されていれば OK です。

Elastic Compute Cloud 2[Instance Index]

Elastic IP の設定

今回の最後に Elastic IP を設定していきます。

EC2サーバーはインターネットに接続を行う場合、どのサーバーも例外なくパブリックIPというものを持つ必要があります。そして、先ほど作成したEC2インスタンスにも作成時にパブリックIPが自動で割り振られるのですが、サーバーを再起動させるたびにこのパブリックIPが変わってしまうという欠点を持っています。

そこで Elastic IP を使用します。
これは、先に固定のIPアドレスを他に使用されないように押さえてしまい、それをパブリックIPとしてEC2インスタンスに紐付けることで、インスタンスの起動、停止に関わらず常に同じIPで通信を行うことができます。

では早速作成していきましょう。

1, 左のメニューバーから「Elastic IP」をクリックしてください。
2, 右上辺りにある「セキュリティグループの作成」をクリックしてください。
3, 「Amazon の IPv4 アドレスプール」が設定されていると思います。
4, そのまま「割り当て」をクリックしましょう。
Elastic IP[一覧]
ここでは既にNameタグを設定していますが、「タグの管理」をクリックすれば設定できます。

次に、このIPを先ほど作成したインスタンスに割り当てましょう。

5, 右上辺りにある「Action」から「Elastic IP アドレスの関連付け」を選択してください。
Elastic IP[割り当て01]
6, 先ほど作成したインスタンスとそのパブリックIPを選択して「関連付ける」をクリックしてください。
Elastic IP[割り当て02]

以下の画面のように、インスタンスが関連づけられていれば OK です。
Elastic IP[割り当て03]

最後に

今回は「サーバー構築編」でした。
次回からやっとコマンドラインを使用することになります(長い!)。

それでは次回「環境構築編」お楽しみに。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ELB(ALB)の設定・接続・確認

内容

Application Load Balancerの設定を行う。
以下のような構成を構築する。
ALB.jpg

前提

・下記構成が既に配置されていること。
・セキュリティグループの通信許可設定がされていること
・EC2にApacheがインストールされていて起動していること

# yum install -y httpd
# systemctl start httpd.service
# systemctl status httpd.service
# ps -ef | grep -v grep | grep apache

ALB2.jpg

手順

各サーバにHTMLファイルを配置する

/var/www/html配下にそれぞれ以下を記載したindex.htmlを配置します。
・ap-northeast-1aにはap-northeast-1aが記載されたファイルを格納します。
・ap-northeast-1cにはap-northeast-1cが記載されたファイルを格納します。

ap-northeast-1a

# vi /var/www/html/index.html
<html><h1>ap-northeast-1a</h1></html>

# cat index.html
<html><h1>ap-northeast-1a</h1></html>

ap-northeast-1c

# vi /var/www/html/index.html
<html><h1>ap-northeast-1c</h1></html>

# cat index.html
<html><h1>ap-northeast-1c</h1></html>

表示確認

それぞれのインスタンスのIPアドレスをコピーしてブラウザに張り付けて
上記のap-northeast-1a、ap-northeast-1cが表示されることを確認します。
これでELBによる振り分けを行った時にそれぞれ1aと1cに振り分けられていることを確認できます。

ss_000.JPG
ss_001.JPG

ALBの作成

ログイン~作成画面まで

[AWSマネジメントコンソール]⇒[サービス]⇒[コンピューティング]⇒[EC2]を選択します。
ss_002.JPG

[EC2ダッシュボード]⇒[ロードバランシング]⇒[ロードバランサー]を選択します。
ss_003.JPG

ロードバランサー一覧画面より[ロードバランサーの作成]を押下します。
ss_004.JPG

ALBの選択

ALB、NLB、CLBの3種類の中からALBを選択します。
ss_006.JPG

ロードバランサーの設定

ロードバランサーの設定を行います。赤枠の部分の設定となります。
ELB2.jpg

今回は外部用なのでインターネット向けでipv4を選択。
プロトコルはHTTPでポートは80を使用。ここでHTTPSを選択すると次の画面で追加設定がありますが今回はHTTP。

設定
スキーム インターネット向け
IPアドレスタイム ipv4
リスナー HTTP:80

ss_007.JPG

セキュリティ設定の構成

今回は特に設定する必要はないです。
ss_008.JPG

セキュリティグループの設定

HTTPの通信許可設定がされているセキュリティグループを作成するか、割り当てを行います。
ss_009.JPG

ルーティングの設定

ここから振り分け先の設定を行います。赤枠の部分となります。
ELB3.jpg

ヘルスチェックの詳細設定は今回すぐにUnHealthyを確認したいので間隔を短くしています。

ターゲットグループ

設定
ターゲットの種類 インスタンス
プロトコル HTTP
ポート 80

ヘルスチェック

設定
プロトコル HTTP
パス /

ss_011.JPG

ターゲットの登録

画面下部にターゲット登録可能な設定が表示されるので選択後[登録済みに追加]を押下します。
※Apacheを起動しておかないと表示されません。

ss_014.JPG

作成完了

[ロードバランサーを正常に作成しました]と表示されればELBの作成が完了となります。
ss_016.JPG

接続確認

[作成したELB]⇒[説明タブ]よりARNをコピーしてブラウザに貼り付けます。
何回か行うとap-northeast-1aap-northeast-1cが表示され、振り分けが行われているのが分かります。

ss_028.JPG

ELB+α

リスナーIDがELBのプロトコルと待ち受けポート(下の図赤枠)で、転送先が設定した振り分け先のターゲットグループ(下の図青枠)となります。
ss_017.JPG

ELB4.jpg

振り分け先が正常か否かはターゲットグループのターゲットタブかモニタリングタブで確認できます。
1aのApacheは停止、1cのApacheは起動している状態だと
1aのステータスはunhealthy、1cのステータスはhealthyとなります。
ELB5.jpg

ss_029.JPG

終わり

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Backup定時備份RDS

0. Intro

有使用過AWS RDS的使用者應該都會了解在RDS本身已經有提供enable auto backup來確保daily都有一份可還原的備份。

而先前AWS也推出集中性管理的AWS Backup console來提供給使用者集中式的管理所有需要備份的計畫與排程,接下來介紹怎麼使用AWS Backup來幫production 的DB做每個小時的備份。

1. 認識AWS Backup

AWS Backup

AWS Backup 是AWS的Centralized Backup console,以往我們在各個AWS資料存儲服務(EC2, EBS/EFS, RDS/DynamoDB等)各自備份的排程任務,都可以在新的Backup console中集中管理。

2. 透過Web console來建立AWS Backup

2.1 新增Backup Plan

首先先從web console到
AWS Console > Service > AWS Backup > Backup Plans > [Create Backup Plan]

Backup Plan Name這邊可以填入任意你可以識別的文字
STEP1

接著Rule name這邊可以輸入 rds-backup-hourly,Schedule的部分因為預設的下拉選單中最短的時間是12小時,所以我們選擇Custom cron expression,填入cron(0 * * * ? *)

其他Backup window(8小時)與lifecycle都可以是預設值,加密的Valut預設也可以用AWS Default即可。

STEP2

STEP3

新增Rule成功後,我們可以繼續來assign 要備份的resource給已經建立的Backup Rule。

2.2 Assign Backup Resource

AWS目前提供了兩種方式來綁定相關的resource
1. 直接指定Resource ID
2. 透過Tag來filter相關的resource,例如所有環境是production的資源,就可以透過env=prod這樣的方式新增。
STEP4

儲存後應該就可以看到相關的資源已經列在Backup Plan下方資源清單中,這樣就可以下班了XD

BTW,前面敘述有提到Backup Window預設是8小時,而我們設定的backup是每小時備份,如果剛設定完的下一個小時沒有開始備份是正常的XD

3. 透過Cloudformation來建立AWS Backup

除了透過web console建立,我們也可以透過Cloudformation來建立整個Backup plan&resources。

直接修改相關的Region/Account ID/DB Instance ID就可以快速的deploy這個stack了~

AWSTemplateFormatVersion: "2010-09-09"
Description: "Hourly Backup Plan for <resources?>"
Parameters:
  AWSAccountID:
    Type: String
    Default: "<AWS Account ID>"
Resources:
  DBBackupPlanWithHourlyBackups:
    Type: "AWS::Backup::BackupPlan"
    Properties:
      BackupPlan:
        BackupPlanName: "rds-prod-hourly-backup"
        BackupPlanRule:
          - RuleName: "RuleForHourlyBackups"
            TargetBackupVault: "Default"
            ScheduleExpression: "cron(0 * * * ? *)"
            StartWindowMinutes: 60
            Lifecycle:
              DeleteAfterDays: 30
  TagBasedBackupSelection:
    Type: "AWS::Backup::BackupSelection"
    Properties:
      BackupSelection:
        SelectionName: "resource-of-rds-prod-hourly-backup"
        IamRoleArn: !Sub arn:aws:iam::${AWSAccountID}:role/service-role/AWSBackupDefaultServiceRole
        Resources: 
          - !Sub arn:aws:rds:<rds region>:${AWSAccountID}:db:<RDS DB Instance Identify Name>
      BackupPlanId: !Ref DBBackupPlanWithHourlyBackups
    DependsOn: DBBackupPlanWithHourlyBackups

4. 使用tags來快速filter需要備份的資源

如果需要透過Tag來大量assign相關的resource,可以將上面的template中的Resources換成下面的表示方式

ListOfTags:
         -
           ConditionType: "STRINGEQUALS"
           ConditionKey: "env"
           ConditionValue: "prod"
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amplify Consoleで複数バージョンのVueアプリケーションのデプロイとFacebook認証

やりたいこと

VueとAmplifyを使って以下のアーキテクチャを構築する。

  • Facebook認証機能を持ったVueアプリケーションの実装
  • production/development の2つのデプロイ環境を作る
  • Githubへのプッシュをフックし、それぞれの環境へデプロイするCIの構築

Vueアプリを作る

vue createしたあとにCSSフレームワークとしてBulmaを組み込む。
Vuetifyとかvue-bulmaを使わないのはただのポリシー。

$ vue create vue-amplify-facebook
$ cd vue-amplify-facebook
$ npm install --save bulma node-sass sass-loader
$ mkdir src/assets/sass
$ touch src/assets/sass/main.scss

src/assets/sass/main.scss

@import "~bulma/bulma";

src/main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

require('./assets/sass/main.scss');

new Vue({
  render: h => h(App),
}).$mount('#app')

http://localhost:8080 で表示を確認したらGithubへコミット。

$ git push -u origin master

Amplifyのセットアップ, ホスティング、CI

VueアプリケーションにAmplifyを組み込む。
Amplify CLのバージョンは以下。

$ amplify -v
4.16.1

initでは特に変わった操作はしていないかな。ほぼほぼデフォルト。

$ amplify init
Note: It is recommended to run this command from the root of your app directory

? Enter a name for the project vue-amplify-facebook

? Enter a name for the environment prod

? Choose your default editor: Visual Studio Code


? Choose the type of app that you're building javascript

Please tell us about your project
? What javascript framework are you using vue

? Source Directory Path:  src

? Distribution Directory Path: dist

? Build Command:  npm run-script build

? Start Command: npm run-script serve

Using default provider  awscloudformation

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html

? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use default

S3へのホスティング設定。
最初の質問で Managed hosting with custom domains,
Continuous deployment
を選ぶ。
これでAmplifyConsoleでのCIがセットアップされる。

$ amplify add hosting

? Select the plugin module to execute Hosting with Amplify Console (Managed hosting with custom domains,
 Continuous deployment)

? Choose a type Continuous deployment (Git-based deployments)

? Continuous deployment is configured in the Amplify Console. Please hit enter once you connect your rep
ository

Amplify hosting urls:
┌──────────────┬──────────────────────────────────────────────┐
│ FrontEnd Env │ Domain                                       │
├──────────────┼──────────────────────────────────────────────┤
│ master       │ https://master.d3bh1ri8gu6eyb.amplifyapp.com │
└──────────────┴──────────────────────────────────────────────┘

できたら作成されたファイルをコミットして、Githubへプッシュ。

$ git push origin master

Amplify ConsoleでCIが走ってVueアプリケーションがS3へデプロイされる。

vue-amplify-facebook_1.png


認証画面のブランチを作る

認証機能を組み込む前に、UI部分を実装する。
Vueのナビゲーションメニューを設置して、そこにFacebook認証ボタンを置く感じに。

※ 別ブランチで作業する。

$ git checkout -b development

Vue画面を編集。

src/components/Auth.vue

展開しないハンバーガーボタンがあるけどご愛嬌で。。

<template>
  <nav class="navbar" role="navigation" aria-label="main navigation">
    <div class="navbar-brand">
      <a class="navbar-item" href="/">
        <h1 class="title">Vue Amplify</h1>
      </a>

      <a
        role="button"
        class="navbar-burger burger"
        aria-label="menu"
        aria-expanded="false"
        data-target="navbarBasicExample"
      >
        <span aria-hidden="true"></span>
        <span aria-hidden="true"></span>
        <span aria-hidden="true"></span>
      </a>
    </div>

    <div class="navbar-menu">
      <div class="navbar-end">
        <div class="navbar-item">
          <div class="buttons">
            <button class="button is-link" @click="signin">
              <strong>SignIn with Facebook</strong>
            </button>
            <button class="button is-light" @click="signout">
              <strong>SignOut</strong>
            </button>
          </div>
        </div>
      </div>
    </div>
  </nav>
</template>

<script>
export default {
  name: "Auth",
  methods: {
    signin() {
      console.log("signin");
    },
    signout() {
      console.log("signout");
    }
  }
};
</script>

表示が確認できたらmasterとは別のブランチへpushする。

$ git push origin development

開発バージョン確認用の環境を作る

開発用ブランチの表示確認をするため Amplify のenvを追加する。

$ amplify env add dev
Note: It is recommended to run this command from the root of your app directory

? Do you want to use an existing environment? No

? Enter a name for the environment dev
Using default provider  awscloudformation

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html

? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use default
Adding backend environment dev to AWS Amplify Console app: d3bh1ri8gu6eyb

Amplify Consoleを開く。

$ amplify console

コンソールから「リポジトリブランチの追加」。
さきほど Githubへpushした developmentブランチを amplify env add で作ったdevと紐付ける。

AWS_Amplify_Console_1.png

設定が完了するとCIが走ってdevelopmentブランチがデプロイされる。
ここまでの操作で以下のように2つのURLが払い出されている。

AWS_Amplify_Console.png

それぞれのURLにアクセスして表示内容が異なっていることを一応確認しておく。


認証機能を追加する

Amplify CLIで認証機能を実装する。
ソーシャルプロバイダでの認証を選択し、リダイレクト先のURLに先ほどデプロイしたmaster, devのURLと、ローカルホストを指定する。

$ amplify add auth
Using service: Cognito, provided by: awscloudformation

 The current configured provider is Amazon Cognito.

 Do you want to use the default authentication and security configuration? Default configuration with So
cial Provider (Federation)
 Warning: you will not be able to edit these selections.

 How do you want users to be able to sign in? Email

 Do you want to configure advanced settings? No, I am done.

 What domain name prefix you want us to create for you? vueamplify-facebook1e4b7722-1e4b7722

 Enter your redirect signin URI: http://localhost:8080/

? Do you want to add another redirect signin URI Yes
 Enter your redirect signin URI: https://master.d3bh1ri8gu6eyb.amplifyapp.com/

? Do you want to add another redirect signin URI Yes
 Enter your redirect signin URI: https://development.d3bh1ri8gu6eyb.amplifyapp.com/

? Do you want to add another redirect signin URI No
 Enter your redirect signout URI: http://localhost:8080/

? Do you want to add another redirect signout URI Yes
 Enter your redirect signout URI: https://master.d3bh1ri8gu6eyb.amplifyapp.com/

? Do you want to add another redirect signout URI Yes
 Enter your redirect signout URI: https://development.d3bh1ri8gu6eyb.amplifyapp.com/

? Do you want to add another redirect signout URI No
 Select the social providers you want to configure for your user pool: Facebook

 You've opted to allow users to authenticate via Facebook.  If you haven't already, you'll need to go to
 https://developers.facebook.com and create an App ID.

 Enter your Facebook App ID for your OAuth flow:  9xxxxxxxxxxxxxx
 Enter your Facebook App Secret for your OAuth flow:  22exxxxxxxxxxxxxxxxxxxxxxx
Successfully added resource vueamplifyfacebook1e4b7722 locally

Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
$ amplify status

Current Environment: dev

| Category | Resource name              | Operation | Provider plugin   |
| -------- | -------------------------- | --------- | ----------------- |
| Auth     | vueamplifyfacebook1e4b7722 | Create    | awscloudformation |
| Hosting  | amplifyhosting             | No Change |                   |


Amplify hosting urls:
┌──────────────┬───────────────────────────────────────────────────┐
│ FrontEnd Env │ Domain                                            │
├──────────────┼───────────────────────────────────────────────────┤
│ development  │ https://development.d3bh1ri8gu6eyb.amplifyapp.com │
├──────────────┼───────────────────────────────────────────────────┤
│ master       │ https://master.d3bh1ri8gu6eyb.amplifyapp.com      │
└──────────────┴───────────────────────────────────────────────────┘

最後に作成したリソースを反映させる。

$ amplify push

Facebook Developers の設定

Facebook側にアプリドメインと有効なOAuthリダイレクトURIを設定する。
設定方法は以下のドキュメントを参考に。

Amplify Javascript - Facebook Instructions

fb.png


Vue app に Amplifyを組み込む

npm install --save aws-amplify

複数のコールバックURLを指定している場合、Amplifyの仕様で複数のコールバックURLの設定が読み込めないので、aws-exports.jsのロード後にwindow.hostnameから適切なリダイレクトURLを判定するコードをいれる。

これに関しては別途まとめているのでそちらを参考に。

Amplify auth は複数のコールバックURLに対応していない

src/main.js

import Vue from "vue";
import App from "./App.vue";
import Amplify from "aws-amplify";
import awsconfig from "./libs/aws-config";

// debug: リダイレクトURLが正しく判定されているか確認のため
console.log(awsconfig.oauth);

Amplify.configure(awsconfig);

Vue.config.productionTip = false;

require("./assets/sass/main.scss");

new Vue({
  render: h => h(App)
}).$mount("#app");

デバッグ用にAmplifyのLoggerを使ってHubで受け取るイベントの内容をコンソールに出力している。

Amplify.Logger.LOG_LEVEL = "INFO";
const logger = new Logger("AmplifyFacebook");

logger.info(event, data);

Facebook認証は以下のような感じ。
これを実行すると各認証プロバイダ用の認証画面へリダイレクトする。

Auth.federatedSignIn({ provider: "Facebook" });

federatedSignIn で認証した後、認証情報を受け取るのにHubを使う。
HubはAmplifyの提供するイベントリスナで、Amplifyで発生する各種イベントの通知を受け取ることができる。
認証が成功するとCLIで指定したリダイレクトURLをリダイレクトされ、Hubを使って認証状態の変更を受け取ることができる。

Hub.listen("auth", ({ payload: { event, data } }) => {
  logger.info(event, data);

  switch (event) {
    case "signIn":
      await this.saveCurrentAuthenticatedUser();
      break;
    case "signOut":
      this.clearCurrentAuthenticatedUser();
      break;
  }
});

最終的なコード。
Amplify Javascript - OAuth and Hosted UI に記載されているReactでの実装を参考にしている。

<template>
  <nav class="navbar is-white" role="navigation" aria-label="main navigation">
    <div class="navbar-brand">
      <a class="navbar-item" href="/">
        <h1 class="title">Vue Amplify</h1>
      </a>

      <a
        role="button"
        class="navbar-burger burger"
        aria-label="menu"
        aria-expanded="false"
        data-target="navbarBasicExample"
      >
        <span aria-hidden="true"></span>
        <span aria-hidden="true"></span>
        <span aria-hidden="true"></span>
      </a>
    </div>

    <div class="navbar-menu">
      <div class="navbar-end">
        <div class="navbar-item">
          <div v-if="isSignedIn" class="buttons">
            <a class="navbar-item">{{ user.attributes.email }}</a>

            <button class="button is-light" @click="signout">
              <strong>SignOut</strong>
            </button>
          </div>
          <div v-else class="buttons">
            <button v-if="!isSignedIn" class="button is-link" @click="signin">
              <strong>SignIn with Facebook</strong>
            </button>
          </div>
        </div>
      </div>
    </div>
  </nav>
</template>

<script>
import Amplify, { Auth, Hub, Logger } from "aws-amplify";

Amplify.Logger.LOG_LEVEL = "INFO";
const logger = new Logger("AmplifyFacebook");

export default {
  name: "Auth",
  data() {
    return {
      user: null
    };
  },
  computed: {
    isSignedIn() {
      return this.user !== null;
    }
  },
  async created() {
    Hub.listen("auth", this.authEventListener);

    await this.saveCurrentAuthenticatedUser();
  },
  methods: {
    signin() {
      Auth.federatedSignIn({ provider: "Facebook" });
    },
    signout() {
      Auth.signOut()
        .then(() => {
          this.user = null;
        })
        .catch(err => logger.warn(err));
    },
    async saveCurrentAuthenticatedUser() {
      try {
        const user = await Auth.currentAuthenticatedUser();
        this.user = user;
      } catch (error) {
        logger.warn(error);
        return null;
      }
    },
    clearCurrentAuthenticatedUser() {
      this.user = null;
    },
    async authEventListener({ payload: { event, data } }) {
      logger.info(event, data);

      switch (event) {
        case "signIn":
          await this.saveCurrentAuthenticatedUser();
          break;
        case "signOut":
          this.clearCurrentAuthenticatedUser();
          break;
      }
    }
  }
};
</script>

1つよくわかっていないことがあって、
Hubで受け取る認証情報と、currentAuthenticatedUserが返す認証情報が微妙に異なるのだよな。
なので↑のコードではHubで認証完了イベントを受け取ってからcurrentAuthenticatedUserを実行して改めて認証ユーザーの情報を取得している。

localhostで動作確認をしてからdevelopmentブランチへpush。
すると再びCIが走ってdev環境へ認証機能を実装したバージョンがデプロイされる。

vue-amplify-facebook.png

デモ

最終的にこんな感じになる。

https://www.youtube.com/watch?v=CLE77Recxx8

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PythonモジュールをLambda Layerにアップロードする時のフォルダ構成について

はじめに

Lambda Layerを使おうとした際にPythonモジュールのフォルダ構成でハマったので、備忘として記事にします。Lambda LayerについてはAWSの公式ドキュメントをご確認ください。

フォルダ構成

プログラミング言語ごとのフォルダ構成については公式ドキュメントでも言及されています。
Pythonの場合、python/配下にLambda Layerで使用するモジュールを配置する必要があります。
例えば以下のようなイメージです。

python
 ├─test1.py
 └─common
   └─test2.py
 

Layerにアップロードするには、上記pythonフォルダをzipファイルにした上でアップロードします。
上記構成を無視してzipファイルを作成してアップロードした場合、当然ですが、Lambdaで使用する際にエラーになります。
最初はなぜエラーになっているかもわからずハマってました。。。ちゃんとドキュメントは確認しないといけないなと反省しました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Excon::Error::Socket: getaddrinfo: Name or service not known (SocketError)というエラー文の対応

環境

$ ruby -v
ruby 2.6.5
$ rails -v
Rails 5.2.4

Amazon Linux 2

状況

本番環境としてデプロイした後に、画像をCarriorwave,fogを通じてS3にアップロードしようとすると、エラーが発生。
エラー文は以下の2種類。

Excon::Error::Socket: getaddrinfo: Name or service not known (SocketError)
SocketError: getaddrinfo: Name or service not known

本件の原因

config/initializer/carrior_wave.rb
if Rails.env.production?
  CarrierWave.configure do |config|
    config.fog_provider = 'fog/aws'
    config.fog_credentials = {
      provider: 'AWS',
      region: 'ap-northeast-1a', # 問題箇所
      aws_access_key_id: 'アクセスキー',
      aws_secret_access_key: 'シークレットキー'
    }
    config.fog_directory = 'バケット名'
    config.cache_storage = :fog
  end
end

'ap-northeast-1a'なんてリージョンはなく、ap-northeast-1の間違いであった。

解決した対応

問題箇所のap-northeast-1aap-northeast-1にしてpumaを再起動した。

こんなしょうもないミスで2時間潰しました笑

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS CDKで快適なクラウド開発

はじめに

このスライドはどこかでLT発表するためにつくりました。今回はAWS CDKを使うメリットについて改めてお話します。


自己紹介


AWS CDKとはなにか?

AWS CDKとは、プログラミング言語を使ってAWSのクラウド環境をプロビジョニングするためのオープンソースのフレームワークである。
AWS CDKではソースコードからCloudFormationを作成してリソースのクラウドへのデプロイを行う。


プロビジョニングとは?

AWSのインフラ環境を構築すること。通常のインフラ構築はマネジメントコンソールを使ってGUI上で行うが、CloudFormationAWS CDKを用いる場合はテンプレートファイル(yaml, json, プロビジョニング言語)上にリソースを定義して行う。


マネジメントコンソールを使う問題点

例えば一度構築したAWSのインフラ環境の再現手順を記録したい場合、以下の2つの手段が思いつく

  1. コンソールで行った操作手順を記録する
  2. AWS CLIで同様の環境構築をするためのシェルスクリプトを書く

直感的に1.2.の方法もやりたくはない。。。


CloudFormationを書くという方法


記述例

jsonもしくはymlの形式で定義ファイルを記述する。以下はDynamoDBの例。

dynamodb.template
"myDynamoDBTable" : {
      "Type" : "AWS::DynamoDB::Table",
      "Properties" : {
        "AttributeDefinitions": [ { 
          "AttributeName" : {"Ref" : "HashKeyElementName"},
          "AttributeType" : {"Ref" : "HashKeyElementType"}
        } ],
        "KeySchema": [
          { "AttributeName": {"Ref" : "HashKeyElementName"}, "KeyType": "HASH" }
        ],
        "ProvisionedThroughput" : {
          "ReadCapacityUnits" : {"Ref" : "ReadCapacityUnits"},
          "WriteCapacityUnits" : {"Ref" : "WriteCapacityUnits"}
        }                
     }
}

定義したリソースをデプロイすることで、AWSのクラウド上に実際にリソースを構築することができる。


CloudFormationの問題点

  • テンプレートファイルの記法を覚える必要がある
    • それなりに独特のルールがあるので一種の言語に近い
  • 構文エラーチェックがやりにくい
    • 一応構文チェックしてくれるツールはある
  • 冗長な構文が増える
    • 共通化したいなら自分でシェルスクリプト書くしかない

AWS CDKを使うという方法


プログラミング言語

以下の言語が選択できる


記述例

TypeScriptでlambda+API Gateway+DynamoDBの環境を記述した例

import * as cdk from '@aws-cdk/core'
import * as lambda from '@aws-cdk/aws-lambda'
import * as apigateway from '@aws-cdk/aws-apigateway'
import * as dynamodb from '@aws-cdk/aws-dynamodb'

export class CdkStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props)

    const table = new dynamodb.Table(this, 'Table', {
      partitionKey: { name: 'key', type: dynamodb.AttributeType.STRING }
    })

    const handler = new lambda.Function(this, 'Handler', {
      runtime: lambda.Runtime.NODEJS_10_X,
      code: lambda.Code.asset('lambda'),
      handler: 'index.handler',
      environment: {
        TABLE_NAME: table.tableName
      }
    })

    table.grantReadWriteData(handler)

    new apigawteway.LambdaRestApi(this, 'Endpoint', {
      handler
    })

  }
}

AWS CDKだとシンプルにわかりやすくテンプレートが作成できる。


AWS CDKのいいところ

  • 使い慣れた構文で書ける
  • 共通化ができる
  • 構文チェックがやりやすい

AWS CDKの問題点

  • CloudFormationでできないことは同様にできない
  • 出て間もないツールなので仕様のアップデートが頻繁に行われる
  • 文献が少ない

詳しい情報


さいごに宣伝


CDKのためにつくったnpmパッケージ

  • cdk-lambda-api
    • Lmbda+API Gatewayのリソースをシンプルに構築できる
  • data-pipeline-d2s-cdk
    • DynamoDBからS3へのバックアップ行うData Pipelineのリソース構築をシンプルにできる

AWS CDK関係で書いた記事


みんなも始めようAWS CDK!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Route53のバックアップを取得する

はじめに

Route53のゾーン情報をバックアップする方法を説明します。
バックアップはBINDのゾーンファイル形式でテキスト出力されます。
Route53はゾーンファイルのインポートが可能なので、Route53を別アカウントに引っ越すことになった場合にも利用できそうです。

手段

cli53を利用します。
https://github.com/barnybug/cli53

検証環境

今回の記事を書くにあたり、以下の環境で確認を行いました。

  • バックアップスクリプト実行環境
    • Linux(CentOS8)
      • aws cli 2.0.4
      • cli53 0.8.17
  • 対象のDNS
    • AWS(Route53)
      • パブリップホストゾーン
      • プライベートホストゾーン

事前準備

AWS側の準備

IAMユーザの作成

Route53の情報を出力できるユーザを作成します。
今回は「AmazonRoute53ReadOnlyAccess」のポリシーをアタッチしました。

Linux(バックアップスクリプト実行)側の準備

AWS CLIのインストール

手順は省略します。
AWSの操作に問題がないかを確認するだけなので AWS CLI自体は必須ではありません。

AWS CLIの認証情報を保存

# 「Access Key ID」と「Secret Access Key」を登録します
aws configure

# Route53の情報が取得できるかを確認します
# (例)ホストしているゾーンの取得
aws route53 list-hosted-zones --query "HostedZones[*].Name" --output text

cli53のダウンロード

https://github.com/barnybug/cli53/releases/latest から最新のバイナリをダウンロードします。

wget https://github.com/barnybug/cli53/releases/download/0.8.17/cli53-linux-amd64
chmod 555 cli53-linux-amd64
mv cli53-linux-amd64 /usr/local/bin/cli53

コマンドのテスト

以下のコマンドを実行して出力結果を確認します。

cli53 export <ホストゾーン ID> または、
cli53 export <ドメイン名>
(例)
cli53 export example.com

バックアップスクリプトの作成

#!/bin/bash

# ホストされているドメインのリストを取得して変数に代入
domain_list=$(cli53 list | sed -e '1d' | awk '{print $2}')

# ドメイン毎に別ファイルでエクスポート
for i in ${domain_list}
do
  cli53 export $i > /tmp/$i`date '+%Y%m%d'`.txt
done

※date でファイルに日付けを付与しています
※ファイルの保存場所は /tmp です
※複数のAWSアカウントを管理している場合はプロファイルの指定が可能です

(例)
cli53 export example.com --profile default

おわりに

AWS CLI(aws route53 list-resource-record-sets)で取得できるjsonやtable、yamlの形式では情報がわかりにくかったので、cli53を使用しました。

参考

Route 53 で設定した DNS レコードをエクスポートする
https://qiita.com/tmtysk/items/6ca808dd9ed13abc1992

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む