継続は力なり

タイトル通り定期的な更新を心掛けるブログです。

Mackerel アンバサダーの一員になりました!

タダです.

この度 Mackerel アンバサダープログラムに招待いただき,アンバサダーの一員に加えていただくことになりました! Mackerel は業務で導入することになったことがきっかけで使い始めたのですが,アンバサダープランを個人アカウントに適用いただいたので普段使えてない機能などますます活用していければと思っております.

f:id:sadayoshi_tada:20210314213527p:plain

mackerel.io

Mackerel を導入した理由

Mackerel を導入したのは冒頭に書いた通りで業務上監視が行き届いてない部分を潰したいという課題感から他の監視系 SaaS を比較検討して導入しています.導入前や導入以降の話は下記の記事に書いているので見てもらえると嬉しいです.

sadayoshi-tada.hatenablog.com

上記の記事に書けてなかったことで自分がいくつかの監視 SaaS から Mackerel を上司に推した理由を書いてなかったので書いていきたいと思います.監視のサービスの中でも導入検討時に以下の点を上司にも推していました.

  • 日本語のサポートを受けられること
  • 監視ができてなかったシステムの必要な監視を賄えること
  • エージェントを仕込めばすぐに監視始められること
  • コスト体系がシンプルかつ試算してみたところ予算内に収まったこと

個人的にサービスを知ってからいいなーと思っていたのが次の2点です.2点目は特に日本生まれだからな部分はあります.

  • 標準提供されている機能だけでなく外部の方が機能開発にコントリュビュートされていて欲しい機能をユーザー側からも作っていること
  • 日本のサービスだから発展を応援したいこと

ということもあり導入にいたり,本日に至るまで自社の運用を支えてもらっています.今後も Mackerel を活用した最適なオペレーションを模索していきます.

アンバサダーになってやっていきたいこと

アンバサダーになったことで今後やっていきたいことがあります.アンバサダープランを適用をしていただいたので普段使えてない機能を活用するのはもちろんなのですが,自分が Mackerel を本格的に使い始めたのが昨年の10月からになるのでまだまだ機能改善要望を出したりするに至るところまで使い込みができていないと思います.が,そんな日が浅い自分だからこその視点で次のアンバサダーの活動をやっていきたいです.

  • 引き続き Mackerel の記事の執筆
    • 検証結果の記事
    • Mackerel 運用にまつわる記事
  • 使ってみた機能の改善要望などのフィードバックやコントリュビュート

ブログでの発信は今後も続けていきます.ここ最近はできていないのですが,新しく運用に組み込みたい機能の検証もやっているのでまた記事を書いていきます! 自分が憧れている OSS のコントリュビュートにお世話になっている Mackerel でも関われるところあれば関わらせてもらえたらと考えてます.

まとめ

Mackerel アンバサダーの一員になったことと導入背景や今後のやりたいことを書いていきました.自分の発信を見ていただいて選んでいただけたのかなと思いますので,今後もブログ以外のアウトプットを通じて Mackerel の魅力をお伝えしていけたらと思っているので今後もやっていくぞ!💪

Aurora のクローン機能を使ったバイナリログレプリケーションを実行してみた

タダです.

以前の記事で Aurora のバイナリログを有効化して DMS の準備をする記事を書きました.ただ,DMS のトラブルシューティングを確認してみるとオブジェクトの作成ができないものがあり,ソースデータベース とターゲットデータベースが同一の場合オブジェクトはネイティブツールを使うことが記載がありました.今回のデータ移行も同一 Aurora 間なのでネイティブな機能であるバイナリログレプリケーションで行う方法を使うために設定方法を確認したのでその内容をまとめていきます.

外部キーとセカンダリインデックスが見つからない

AWS DMS は、テーブル、プライマリキー、場合によっては一意のインデックスを作成しますが、効率的にソースからデータを移行するために必要ではない他のオブジェクトは作成されません。たとえば、セカンダリインデックス、非プライマリキーの制約、データデフォルトは作成されません。

データベースからセカンダリオブジェクトを移行するには、ソースデータベースと同じデータベースエンジンに移行中の場合、データベースのネイティブツールを使用します。ソースデータベースで使用したものとは異なるデータベースエンジンに移行してセカンダリオブジェクトを移行する場合は、AWS Schema Conversion Tool (AWS SCT) を使用します。

Aurora 間でのバイナリログレプリケーション

Aurora から Aurora へのバイナリログレプリケーションの方法は下記のドキュメントで紹介されてますが,ドキュメントではスナップショットから復元するパターンです.この記事ではクローン機能を使って確認したのでその内容で整理します.

docs.aws.amazon.com

バイナリログレプリケーションのためにやることは大きく3つです.

  1. クラスターパラメーターグループのbinlog_formatのパラメーターをMIXEDに変更
  2. レプリケーション元の Aurora でレプリケーション用ユーザーとバイナリログ保存期間を設定
  3. Aurora をクローンしてクローンしたクラスターでレプリケーションを実行

1.クラスターパラメーターグループのbinlog_formatのパラメーターをMIXEDに変更

Aurora クラスターパラメーターグループのbinlog_formatのパラーメーターをMIXEDに変更します.バイナリログの有効化のために WRITER 側のインスタンスを再起動します.再起動後,バイナリログの記録ファイルが出る状態になっていることを確認します.

mysql> show global variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+
1 row in set (0.01 sec)
mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | MIXED |
+---------------+-------+
1 row in set (0.00 sec)
mysql> show binary logs;
+----------------------------+-----------+
| Log_name                   | File_size |
+----------------------------+-----------+
| mysql-bin-changelog.000001 |       120 |
| mysql-bin-changelog.000002 |     43424 |
+----------------------------+-----------+
2 rows in set (0.00 sec)

2. レプリケーション元の Aurora でレプリケーション用ユーザーとバイナリログ保存期間を設定

次にレプリケーション元の Aurora でレプリケーション用ユーザーとバイナリログ保存期間を設定します.まずレプリケーションユーザーですが,今回ドキュメント記載の repl_user と権限で作っています.

mysql> CREATE USER 'repl_user'@'%' IDENTIFIED BY '<パスワード>';
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'repl_user'@'%' IDENTIFIED BY '<パスワード>'
Query OK, 0 rows affected (0.01 sec)

ユーザー作成後,レプリケーションが終わるまでのログの保存期間を設定するため,バイナリログ保存期間を指定します.確認した限りですが,ドキュメント記載の最大値は 2,160 (90 日)はエラーが出て利用者側で指定できるのは168(7日間)までのようなのでこの値で指定します.なお,最大値の期間を指定するためには AWS サポートへの問合せが必要になることが AWS サポートへの問合せで教えていただきました.

mysql> CALL mysql.rds_set_configuration('binlog retention hours', 168);
Query OK, 0 rows affected (0.02 sec)

3. Aurora をクローンしてクローンしたクラスターでレプリケーションを実行

準備ができたのでレプリケーション先の Aurora クラスターをクローン機能で複製します.復元したクラスターの WRITER インスタンスのログイベントを確認します.写真のイベントだとログファイル000118245880の箇所でバイナリログが切れています.レプリケーションを確認したバイナリログの番号と開始位置から開始していきます. f:id:sadayoshi_tada:20210313195906p:plain

mysql> CALL mysql.rds_set_external_master ('<レプリケーション元の Aurora WRITER エンドポイント>', 3306, 'repl_user', '<パスワード>', 'mysql-bin-changelog.000118', 245880, 0);`
Query OK, 0 rows affected (0.19 sec)
mysql> CALL mysql.rds_start_replication;
+-------------------------+
| Message                 |
+-------------------------+
| Slave running normally. |
+-------------------------+
1 row in set (1.02 sec)

SHOW SLAVE STAUS でチェックしてSeconds_Behind_Masterが0になるまでいきます.自分が検証したエラーとしてレコード重複のメッセージがでてきて無視していいものはCALL mysql.rds_skip_repl_error;でスキップしたり,外部キー制約で同期できなかったレコードはSET FOREIGN_KEY_CHECKS = 0を無効化して同期していきました.

mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: xxxx.ap-northeast-1.rds.amazonaws.com
                  Master_User: repl_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin-changelog.000118

~中略~
              Seconds_Behind_Master: 0
~中略~
1 row in set (0.00 sec)

まとめ

Aurora クラスター間のバイナリログレプリケーションを行う方法をクローン機能使った場合で整理してみました.個人的にクローンを初めて使ったのですが,高速に復元できてすぐにレプリケーションを走らせられたのがとても良い体験でした.今後こういったレプリケーションは Aurora のバージョンアップの時にも使っていけるかと思ったのでその時は適宜使っていきます.

docs.aws.amazon.com

関連記事

sadayoshi-tada.hatenablog.com

プルリクマージ後に AWS SAM と GitHub Actions を使った差分デプロイフローを作ってみた

タダです.

以前モノリポに格納されているコードの中で変更があったコードのみ AWS SAM と GitHub Actions のデプロイフローを検証した記事を書いたのですが,投入したところプルリクをマージした後にデプロイがうまくいきませんでした.この記事でうまくいかなかったところとどう回避したかを書いていきます.

sadayoshi-tada.hatenablog.com

どこがうまくいかなかったのか

早速どの辺がうまくいかなかったのかなんですが,プルリクのマージ後にBuild & Deployのセクションの処理が差分を検知せずに処理が終わってしまいました.恐らくプルリクが発生した段階ではマージ先とマージ元の差分があるが,マージされた後だとその差分がなくなるため差分検知がなくなったため下記の定義では差分デプロイができなくなったと推測しました.

on:
  pull_request:
      types: closed
    paths:
      - '**app.py'

env:
  TARGET_BRANCH: ${{ github.base_ref }}

jobs:
  sam-test:
    runs-on: ubuntu-latest
    steps:
      - name: 'Checkout'
        uses: actions/checkout@v2

     - name: 'Fetch'
        run: git fetch --depth 1 origin ${TARGET_BRANCH}

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: '3.7'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install awscli
          pip install aws-sam-cli

      - name: Configure AWS credentials for prod
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION}}

      - name: Build & Deploy
        run: |
          for FILE in $(git diff origin/${TARGET_BRANCH} HEAD --diff-filter=AM --name-only -- "*app.py") ; do
            cd $(dirname ${FILE}); cd ../
            STACK_NAME=`pwd | awk -F "/" '{ print $NF }'`
            sam build --use-container
            sam package --template-file template.yaml --output-template-file packaged.yaml --s3-bucket ${{ secrets.AWS_SAM_BUCKET }} --region ${{ secrets.AWS_REGION}}
            sam deploy --template-file packaged.yaml --stack-name ${STACK_NAME} --s3-bucket ${{ secrets.AWS_SAM_BUCKET }} --region ${{ secrets.AWS_REGION}} --capabilities CAPABILITY_IAM
            cd ../
          done

どのように問題を回避したか

うまくいかなかった差分デプロイを2つのステップに分割して問題を回避するようにしました.以下 YAML ファイルで変更した部分だけ抜粋して記載します.

on:
  push:
    branches:
      - master
  pull_request:

jobs:
  sam-tes:
    runs-on: ubuntu-latest
    steps:
      ~中略~
      - name: Package
        if: contains(github.event_name, 'pull_request')
        env:
          TZ: 'Asia/Tokyo'
        run: |
          # Set variables
          DATE=`date +"%Y%m%d"`
          # sam packaged
          for FILE in $(git diff origin/${TARGET_BRANCH} HEAD --diff-filter=AM --name-only -- "*app.py") ; do
            cd $(dirname ${FILE}); cd ../
            STACK_NAME=`pwd | awk -F "/" '{ print $NF }'`
            sam package --template-file template.yaml --output-template-file ${DATE}-${STACK_NAME}.yaml --s3-bucket ${{ secrets.AWS_SAM_BUCKET }} --region ${{ secrets.AWS_REGION}}
            aws s3 cp ${DATE}-${STACK_NAME}.yaml s3://${{ secrets.AWS_SAM_BUCKET }}
            cd ../
          done

      - name: Deploy
        if: contains(github.event_name, 'push')
        env:
          TZ: 'Asia/Tokyo'
        run: |
          # Set variables
          DATE=`date +"%Y%m%d"`
          aws s3 cp s3://${{ secrets.AWS_SAM_BUCKET }} . --recursive --exclude '*' --include "${DATE}*.yaml"
          for FILE in `\find . -name "${DATE}*.yaml"` ; do
            echo ${FILE}
            STACK_NAME=`echo ${FILE} | cut -c12- | sed 's/\.[^\.]*$//'`
            sam deploy --template-file ${FILE} --stack-name ${STACK_NAME} --s3-bucket ${{ secrets.AWS_SAM_BUCKET }} --region ${{ secrets.AWS_REGION}} --capabilities CAPABILITY_IAM
          done
          aws s3 rm s3://${{ secrets.AWS_SAM_BUCKET }} --recursive --exclude '*' --include "${DATE}*.yaml"

YAML で行った変更ですが,ざっくり次の対応をしています.この変更を行うことで差分デプロイを通すことができました.

  1. onセクションで,プルリクイベント発生時とマージ後のイベントを検知するようにした
  2. sam packagesam deployの処理をプルリクイベント発生時とマージ後に分けて処理するようにして,sam packageで生成したファイルを一時的に S3 にアップロード/ダウンロードしてデプロイし,デプロイ後に S3 にアップロードしたファイルを削除

まとめ

モノリポにおける AWS SAM と GitHub Actions を使った差分デプロイでうまくいかなかったこととその回避したアプローチを書きました.もっと良い方法があるかもしれないとは思っているのですが,自分の中で解がでなかったのでもしより良い方法あったら教えていただけると幸いです🙇‍♂️

SSM Run Command をメンテナンスウィンドウで実行する

タダです.

業務の中で日時を決めて SSM Run Command を実行したい要件がでてきたのでメンテナンスウィンドウを使ってみることにしました.この記事ではメンテナンスウィンドウを AWS CLI を使って設定して行ったメモを備忘録として書いていきます.

メンテナンスウィンドウとは

メンテナンスウィンドウは Systems Manager 関連のサービスで期間や日時を指定したりしてタスクを実行することができます.サポートされているタスクタイプは次の4つです.

  • Systems Manager Run Command コマンド
  • Systems Manager オートメーションワークフロー
  • AWS Lambda 関数
  • AWS Step Functions タスク

docs.aws.amazon.com

AWS CLI での設定コマンド

1. メンテナンスウィンドウの作成

メンテナンスウィンドウは create-maintenance-window で作っていきます.レスポンスで返ってきているWindowsIdがメンテナンスウィンドウを識別する ID です.2時間の間5分毎にタスクを実行するメンテナンスウィンドウになっています.

aws ssm create-maintenance-window \
    --name "test-maintenance-window" \
    --schedule "rate(5 minutes)" \
    --duration 2 \
    --cutoff 1 \
    --allow-unassociated-targets
{
    "WindowId": "mw-xxxx"
}

2. メンテナンスウィンドウでターゲットの登録

メンテナンスウィンドウのタスク実行先(ターゲット)を設定していくには register-target-with-maintenance-window を使います.EC2 に対してコマンドを実行したいのでそのようなパラメータになっています.

aws ssm register-target-with-maintenance-window \
    --window-id "mw-xxxx" \
    --resource-type "INSTANCE" \
    --target "Key=InstanceIds,Values=i-xxx"
{
    "WindowTargetId": "xxxx-xxxx-xxxx-xxxx-xxxx"
}

3. ターゲットに対して実行するタスクの登録

メンテナンスウィンドウとターゲットの登録が完了したので,ターゲットに実行したいタスクを登録していきます.Run Command を登録したいので register-task-with-maintenance-window を使って登録します.lsコマンドを実行するだけのタスクを登録しました.

aws ssm register-task-with-maintenance-window \
    --window-id mw-xxx \
    --task-arn "AWS-RunShellScript" \
    --max-concurrency 1 --max-errors 1 \
    --priority 10 \
    --targets "Key=InstanceIds,Values=i-xxxx" \
    --task-type "RUN_COMMAND" \
    --task-invocation-parameters '{"RunCommand":{"Parameters":{"commands":["ls"]}}}'
{
    "WindowTaskId": "xxxx-xxxx-xxxx-xxxx-xxxx"
}

タスクの実行状況はdescribe-maintenance-window-executionsで確認できます.確認したみたところ,SUCCESSステータスになっているので問題なさそうです.

aws ssm describe-maintenance-window-executions \
    --window-id mw-xxxx
{
    "WindowExecutions": [
        {
            "WindowId": "mw-xxxx",
            "WindowExecutionId": "xxxx-xxxx-xxxx-xxxx-xxxx",
            "Status": "SUCCESS",
            "StartTime": "2021-03-07T22:52:36.863000+09:00",
            "EndTime": "2021-03-07T22:52:43.710000+09:00"
        },
        {
            "WindowId": "mw-xxxx",
            "WindowExecutionId": "xxxx-xxxx-xxxx-xxxx-xxxx",
            "Status": "SUCCESS",
            "StatusDetails": "No tasks to execute.",
            "StartTime": "2021-03-07T22:47:36.990000+09:00",
            "EndTime": "2021-03-07T22:47:37.026000+09:00"
        },
        {
            "WindowId": "mw-xxxx",
            "WindowExecutionId": "xxxx-xxxx-xxxx-xxxx-xxxx",
            "Status": "SUCCESS",
            "StatusDetails": "No tasks to execute.",
            "StartTime": "2021-03-07T22:42:36.936000+09:00",
            "EndTime": "2021-03-07T22:42:36.969000+09:00"
        },
        {
            "WindowId": "mw-xxxx",
            "WindowExecutionId": "xxxx-xxxx-xxxx-xxxx-xxxx",
            "Status": "SUCCESS",
            "StatusDetails": "No tasks to execute.",
            "StartTime": "2021-03-07T22:37:36.723000+09:00",
            "EndTime": "2021-03-07T22:37:36.758000+09:00"
        }
    ]
}

4. メンテナンスウィンドウの時間を更新する

このままだと5分に一回コマンドが実行され続けるので時間部分を更新しておきます.今回は一度だけ実行したいメンテナンスウィンドウに更新したいのでat(UTC時間)で日時を指定してみます.メンテナンスウィンドウを更新するには update-maintenance-windowを使います.日本時間の2021/03/07 23:00の日時を指定しています.

aws ssm update-maintenance-window \
    --window-id mw-xxxx \
    --schedule "at(2021-03-07T14:00:00)"
{
    "WindowId": "mw-xxxx",
    "Name": "test-maintenance-window",
    "Schedule": "at(2021-03-07T14:00:00)",
    "Duration": 2,
    "Cutoff": 1,
    "AllowUnassociatedTargets": true,
    "Enabled": true
}

実行状況を確認してみます.23時にタスクが実行されていました.

 aws ssm describe-maintenance-window-executions \
    --window-id mw-xxxx
{
    "WindowExecutions": [
        {
            "WindowId": "mw-xxxx",
            "WindowExecutionId": "xxxx-xxxx-xxxx-xxxx-xxxx",
            "Status": "SUCCESS",
            "StartTime": "2021-03-07T23:00:17.287000+09:00",
            "EndTime": "2021-03-07T23:00:23.046000+09:00"
        },
        {
            "WindowId": "mw-xxx",
            "WindowExecutionId": xxxx-xxxx-xxxx-xxxx-xxxx",
            "Status": "SUCCESS",
            "StartTime": "2021-03-07T22:57:36.885000+09:00",
            "EndTime": "2021-03-07T22:57:42.674000+09:00"
        },

まとめ

AWS CLI を使ってメンテナンスウィンドウを登録して Run Command を実行できるようにしてみました.Systems Manager の活用を進めており,Run Command や処理をまとめた Document,Automation を使うため Systems Manager ファミリーを使い慣れておきたく今回使ってみました.定型処理はまとめてしまってメンテナンスウィンドウを活用していきたいと思います.

関連記事

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

Alexa スキル開発の専門知識を証明する『AWS 認定 Alexa Skill Builder Speciality』に合格するためにやったこと

タダです.

勉強の一環で2/27 に「AWS 認定 Alexa Skill Builder Speciality」を受けて合格しました.今回は自分がどんな勉強をしたかを振り返り,今後受験される方の勉強の参考になればと思い書いていきます.なお,3/22が受験できるラストチャンスで今後受験できなくなるのでその点は注意です.

AWS 認定 Alexa スキルビルダー – 専門知識の認定試験は、2021 年 3 月 22 日が最終の受験日となります。

aws.amazon.com

試験範囲について

試験範囲については試験のガイドで確認できます.Alexa スキルの開発,テスト,公開,運用するにあたる知識が問われそうだと理解しました.

AWS 認定 Alexa スキルビルダー – 専門知識 (AXS-C01)」試験は、Alexa スキル開発者ロールの人を対象としており、Amazon Alexa スキルの作成、テスト、公開、および認定についての理解度を評価するものです。

この試験で評価する能力は次のとおりです。

・ 音声の有用性について説明する。

・ ユーザーエクスペリエンスをデザインする。

・ スキルを構成するアーキテクチャを設計する。

・ スキルに対する AWS および Alexa のセキュリティベストプラクティスに従う。

・ スキルを開発、テスト、検証、トラブルシューティングする。

・ スキル公開プロセスを管理し、Alexa 開発者コンソールを使用する。

・ スキルの運用とライフサイクルを管理する。

試験の比率

試験の割合が以下のようになっています.分野2,4,5の比重が高くなっているのでこの分野を中心に勉強していく方が良いかと感じました.

試験分野 試験における比重
分野 1: 音声ファーストのデザイン手法および機能 14%
分野 2: スキルデザイン 24%
分野 3: スキルアーキテクチャ 14%
分野 4: スキル作成 20%
分野 5: テスト、検証、トラブルシューティング 18%
分野 6: 公開、運用、およびライフサイクル管理 10%

試験勉強で注力したこと

次に,試験に向けて注力して勉強したことをまとめていきます.大きく3つのことをやりました.

1. Alexa 道場の動画を確認する

Alexa 道場という Alexa スキルを作るために必要な用語や機能を教えてくれる講座があります.ここで基本的な専門用語を理解しました.Season 1-6 を確認しました.

developer.amazon.com

2. ドキュメントを読む

Alexa 道場でわからなかった用語やトピックをドキュメントで確認して理解するようにしました.

developer.amazon.com

3. サンプル問題と模擬問題を解く

Alexa 道場とドキュメントの勉強をして,あとはひたすらサンプル問題と模擬問題で知識の確認をしてきました.ここで解けなかった問題をドキュメントでも振り返っていきました.

試験の結果

試験の結果は750点の合格ラインで815点でした. f:id:sadayoshi_tada:20210228193243p:plain

まとめ

AWS 認定 Alexa Skill Builder Speciality」に向けて勉強した内容をおおまかにまとめました.試験廃止かなりギリギリで合格したので,いわゆる12冠になれました.次は「Solution Architect Professional」の有効期限が4月中に切れるため再認定試験を受けます!

f:id:sadayoshi_tada:20210228200034p:plain

関連記事

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com