snaqme Engineers Blog

おやつ体験BOX snaq.me エンジニアによる開発プロダクトブログ

サービススケールに対応していくための既存アーキテクチャ再構成の取り組み

こんにちは!SRE を担当している多田です(@tada_infra).

お客様のおかげで snaq.me はサービス開始から5年が経ちました.これからもサービスのスケールに合わせてシステム側もその変化に対応していけるように既存システムの課題から構成を見直し,改善を試みたのでその模様をこの記事でお伝えしていきます.

prtimes.jp

既存アーキテクチャにおける課題

弊社のシステム基盤は AWS を採用しておりその上で様々なシステムが稼働しています.これまではお客様への迅速なサービス提供を最優先に取り組んできてアーキテクチャの改善は後手になっていたと思います.私が専任で AWS 周りを管理していく立場で昨年入社し,改めて稼働しているシステムの設定を見た時にいくつかの課題があると感じました.今回は構成変更に伴う部分を抜粋して列挙しますが,大きく2点です.

課題1 VPC にパブリックサブネットしかない

EC2,ECS,RDS,ElastiCache,Lambda,Batch,ELB といった VPC 内に展開しているリソースを配置しているネットワークセグメントがパブリックサブネットでサブネットはそれしかありませんでした.ELB はインターネットから直接アクセスを受けるのでいいのですが,それ以外のリソースは直接インターネットからのアクセスを受けないためパブリックサブネットに配置しておく必要はなかったです.この状態のままリソースが増え続けていたので今後もこのままだと懸念を抱えたまま管理することになるため,本来配置しておくべきネットワークセグメントに移動したいという課題感を持ちました.

改善前の AWS 構成イメージ f:id:sadayoshi_tada:20210324175631p:plain

課題2 セキュリティグループの設定の問題

次の課題はセキュリティグループの設定です.セキュリティグループの設定で2つの課題を抱えていました.1つ目は下記のようにインバウンドで受け付けるのがプロトコルALLだったり,通信元の制御として 0.0.0.0/0 が EC2,RDS の設定で定義されていたままでした.セキュリティグループのインバウンドで受け付けるのにこの定義は広範過ぎるかつセキュリティ的にも突かれてしまう危険性を孕んでいる状態でした.

あるセキュリティグループのインバウンドルールのイメージ

セキュリティグループのインバウンドプロトコル IPアドレス範囲
ALL 0.0.0.0/0
HTTP 0.0.0.0/0
HTTPS 0.0.0.0/0
カスタムTCP 0.0.0.0/0

2つ目の課題は上記のようなセキュリティグループが複数のサーバーに跨って設定されていました.例えば,EC2 のセキュリティグループが Lambda,RDS などといった関連ではないリソース間で使いまわされていました.不要なポート開放となるため最低限なポート開放にできるよう1つ目の課題と合わせて解消していく必要があると課題と認識しました.

アーキテクチャの見直しと変更

上記のようなネットワーク設定に起因する課題感からアーキテクチャを見直して変更を加えていきました.

1. プラベートネットワークセグメントの追加

まずはコンピューティングリソースやデータベース郡をプライベートサブネットに移動させたいと思い,サブネットを追加していくことにしました.加えてプライベートサブネットに移動することに伴いインターネットへの疎通のための経路として NAT GatewayVPC エンドポイントを作ってサービス間通信が継続できるような見直しをかけていきました.見直し後の結果のアーキテクチャイメージが下の図になります.これでパブリックにおいていたリソースをプライベートに配置しなおせました.

改善後の AWS 構成イメージ f:id:sadayoshi_tada:20210324185315p:plain

合わせてプライベートサブネットに EC2 も移動したことに伴いこれまでは SSH での接続だったところを Session Manager での接続に全移行しています.また,開発における開発者からのDB への接続は AWS Client VPN 経由でプライベートサブネットの Aurora に繋げるように変更しています.

2. セキュリティグループの作り直しと最適化

セキュリティグループの改善としてサーバーごとにセキュリティグループ定義を作り直して付け直していきました.AWS のサービス間通信はセキュリティグループの ID 同士でインバウンドトラフィックで絞るということもルール化していきました.

改善後の EC2 のインバウンドルールのイメージ

セキュリティグループのインバウンドプロトコル IPアドレス範囲
HTTP sg-xxxxxxxxxxxxxxxx(ELB のセキュリティグループ ID)

3. 変更の伴う箇所におけるルールをドキュメント化

そして,私が変更をかけた部分について考えをドキュメント化して共有するようにしていきました.私の頭の中にあるだけでは今後メンバーが増えた時に変更をかける時に私がボトルネックになってしまって進めるスピードが落ちてしまうのではないかという懸念から考えを文書化していきました.画像は今回の変更に関わるネットワークのルールを書いたページの抜粋部分ですが,これに限らず今後も設計や運用の考えをドキュメント化していきます.

f:id:sadayoshi_tada:20210326111630p:plain

まとめ

ネットワーク設定に関わる課題感から既存本番システムのアーキテクチャ変更に伴う取り組みをまとめました.個人的には DB のサブネット移行と切り替えのタイミングはドキドキが止まらず,終わった後も数日間業務が止まらないかソワソワしていました.この点,予め影響範囲の確認や取り進め方の相談など CTO 三好のサポートがあり危機的な業務停止はなく動いています.この取り組みでネットワーク周りやアーキテクチャの見直しを図れましたが,他にも課題はあるのでカイゼンをしてよりよいシステムの形を目指していきます.

『JAWS DAYS 2021 - re:Connect -』でシステムリリースフローの刷新の取り組みを話してきた

こんにちは!SRE を担当している多田です(@tada_infra).

3/20 開催の「JAWS DAYS 2021 - re:Connect -」にて「スタートアップ企業での散乱したシステムリリースフローをととのえる話」というタイトルでオンライン登壇させていただきました.開発者が安心かつスムーズなリリースフローを作り、開発生産性を向上させたいと言う課題感からリリースフロー刷新に取り組んだお話をしました.この記事で発表を振り返ってきます.

jawsdays2021.jaws-ug.jp

発表資料

発表資料はこちらです.

発表の振り返り

発表した取り組みはリリース周りでまだ仕組み化されてなかったり,複雑になっていることで開発のやりづらさがあるのではないかという課題感や開発サイドへのヒアリングから刷新をしていくことにしました.

改善に向けての取り組みはいくつかの記事でも紹介しておりましたが,GitHub Actions を中心にした形に変えていき,GitHub を見ればリリースに関する設定もわかるし開発者も慣れているツールだから最悪自分がいなくなってもリリースが止まることはないだろうとも思い,採用していきました.また,慣れているからこそ GitHub Actions の処理がうまくいかない時は助言もくれたりしてくれています.

関連記事

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

システムリリースの部分で課題に感じたところの刷新をしていけたのですが,デプロイしているコードの中にはテストが十分に書けてなかったりしてリリースフローに組み込めてなかったり,発表の中で触れたまとまったコマンドスクリプトがうまくいかない事象が発生し始めたので原因究明して改善していかないといけなかったりと課題が残っているのを潰してよりよい仕組みに育てていければと思います.とはいえ,開発者からはいいリアクションをもらっているのはありがたいことです.

質問への回答

発表に対するツイートで反応くださった方ありがとうございました! 拙い発表においてよかったとリアクションをいただけたりして大変ありがたかったです🙇‍♂️ Twitter で質問いただいていたことについて回答させていただきます.

Q. デプロイのスクリプトがサーバーによって異なるのはなぜか?

デプロイスクリプトがサーバーごとに違うことについて質問いただいていました.ヒアリングの時に判明したのがリリースの対象サーバーにコードを git pull する処理やミドルウェアの再起動などといった処理は共通しているのですが,Railsdb:migrate 処理が1台のサーバーだけで実行するようにしているため特定のサーバーのみは処理が現状異なっています.

Q. DB は1つなのか?

今後の改善で別れる場合もあるのですが,DB は現状1つです.

Q. どのタイミングで GitHub Actions を実行しているのか?

GitHub Actions ですが,EC2 のシステムはプルリクマージ後に指定した時間に Run Command を走らせる設定を定義できるように設定していくようにしています.Lambda/Step Functions は2つのタイミングで走っててプルリクが上がってきたタイミングで差分検出した結果を一時的に S3 に入れるのと,マージ後にデプロイする処理が走っています.

まとめ

登壇の振り返りや質問いただいたことを書いてみました.いつもは JAWS DAYS は見るだけな参加を数年続けてきて CFP を出したのは二回目で登壇の機会は初めていただけたので大変ありがたかったです! 登壇者として準備にあたりリハーサルや,配信環境,PR,マイクを送っていただいたりと運営の皆様の手厚いサポートや熱量を非常に感じたイベントでした.また登壇できるように AWS の使い込んで発表していければと思います.ありがとうございました!!

元記事

元記事はこちらです.

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

こんにちは!SRE を担当している多田です(@tada_infra).

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

f:id:sadayoshi_tada:20210314213527p:plain

mackerel.io

Mackerel を導入した理由

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

labs.snaq.me

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

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

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

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

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

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

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

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

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

まとめ

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

元記事

元記事はこちらです.

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

こんにちは!SRE を担当している多田です(@tada_infra).

本番稼働中の Aurora のデータを別の Aurora に移行するために DMS を使おうと思いバイナリログを有効化して 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

関連記事

labs.snaq.me

元記事

元記事はこちらです

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

こんにちは!SRE を担当している多田です(@tada_infra).

業務の中で日時を決めて 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 ファミリーを使い慣れておきたく今回使ってみました.定型処理はまとめてしまってメンテナンスウィンドウを活用していきたいと思います.

元記事

元記事はこちらです.

カスタムランタイム の Lambda をコンテナイメージ化してみた

こんにちは!SRE を担当している多田です(@tada_infra).

Lambda のアップデートで昨年の re:Invent でコンテナがサポートされました.

aws.amazon.com

自前のコンテナイメージを実行できるならカスタムランタイムで設定している Lambda の処理をコンテナイメージ化してみようと思い,下記の記事でカスタムランタイムで実行していた Lambda をコンテナイメージ化して変更してみました.この記事で対応内容を書いていきます.

sadayoshi-tada.hatenablog.com

コンテナサポート対応設定

実行環境のコンテナは ECR に格納する必要があり,これまでとの違いは Dokcerfile を用意する必要がある点です.AWS から Lambda のコンテナイメージが提供されており,そのイメージを使っていきます.

サポートされているすべての Lambda ランタイム (Python、Node.js、Java、.NET、Go、Ruby) のベースイメージを提供しているため、コードと依存関係を簡単に追加することができます。Amazon Linux ベースのカスタムランタイム用のベースイメージも用意しており、これを拡張して Lambda ランタイム API を実装する独自のランタイムを含めることができます。

f:id:sadayoshi_tada:20210127081551p:plain gallery.ecr.aws

ECR に格納する Dockerfile を次のように定義しました.AWS CLI を使った処理を行ったので AWS CLI を入れて,カスタムランタイムで使っていた bootstrap とカスタムランタイムの関数内で書いていたロジックをスクリプト化して実行するようにしました.

Dockerfile

FROM public.ecr.aws/lambda/provided:latest
RUN yum install -y awscli
COPY bootstrap /var/runtime/bootstrap
COPY xxx.sh /var/runtime/xxx.sh
RUN chmod 755 /var/runtime/bootstrap /var/runtime/xxx.sh
CMD ["xxx.handler"]

bootstrap

#!/bin/sh
set -euo pipefail
# Initialization - load function handler
source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh"
# Processing
while true
do
  HEADERS="$(mktemp)"
  # Get an event. The HTTP request will block until one is received
  EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
  # Extract request ID by scraping response headers received above
  REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
  # Run the handler function from the script
  RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")
  # Send the response
  curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response"  -d "$RESPONSE"
done

ECR にコンテナイメージをプッシュする

コンテナイメージを ECR に格納していきます.ECR で表示するコマンドを順次実行していきます.

# ECR ログイン
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxx.dkr.ecr.ap-northeast-1.amazonaws.com
# Dockerfile のビルド
docker build -t xxx .
# タグつけ
docker tag xxx:latest xxx.dkr.ecr.ap-northeast-1.amazonaws.com/xxx:latest
# イメージのプッシュ
docker push xxx.dkr.ecr.ap-northeast-1.amazonaws.com/xxx:latest

Lambda 関数の設定

ECR にコンテナイメージを格納できたら Lambda 関数を作っていきます.これまでの差異は関数作成時にコンテナイメージを選択することです.前の工程でプッシュしたイメージのlatestバージョンを選択して,他の設定を行って Lambda 関数をデプロイします.

f:id:sadayoshi_tada:20210129004551p:plain f:id:sadayoshi_tada:20210129004640p:plain

デプロイ後のコード部分を見に行くとコンテナイメージがデプロイされているからコードは見えない仕様になっています.イベント発火後の処理をコンテナ内で設定しておけばこれまで通りカスタムランタイムの Lambda で実行していたのと同様の処理を実行できました.

f:id:sadayoshi_tada:20210129004856p:plain

まとめ

カスタムランタイムの Lambda をコンテナイメージに置き換えたのでその対応をまとめました.カスタムランタイムの Lambda をデプロイするのに Lambda Layer の設定が必要でコードの他にも管理するものがありましたが,コンテナイメージをメンテするだけで同じことができるようになったのは管理範囲が狭まりました.開発時にコンテナイメージを使って開発しているのであれば,開発・デプロイがしやすいのかと思いました.自社でも普及していきたいと思います.

元記事

元記事はこちらです.

JTF2021w で『スタートアップ企業でのAWS マルチアカウント運用の実践と普及』と題して#推しテクを発表した

こんにちは!SRE を担当している多田です(@tada_infra).

1/24 開催の「July Tech Festa 2021 winter #推しテク総選挙」にて「スタートアップ企業でのAWS マルチアカウント運用の実践と普及」という AWS 管理をしていくなかでアカウントを分割し,組織に分離したアカウントを使ってもらえるよう浸透させていく取り組みをお話ししました.この記事で発表を振り返ってきます.

techfesta.connpass.com

発表資料

発表資料はこちらです.

当日の発表は後日 YouTubeアーカイブされるので他のセッションも見えてなくて残念...と思っている方は是非登録することをオススメします. www.youtube.com

他のセッションの発表資料も connpass の資料一覧から見ることができます.

techfesta.connpass.com

発表の振り返り

発表は以前の JAWS-UG 朝会で発表していたものをアップデートした内容なんですが,当時はマルチアカウント化しはじめた頃でとりあえずステージング出来たくらいのタイミングでした.その頃からステージングが使われず,普及のために動き出したことがアップデートとして話せたと思います.

sadayoshi-tada.hatenablog.com

発表で言えてなかったこととして,課題に感じたアーキテクチャの変更が1アカウントのままだとやり辛いことの中でシステム全体も含んでいたのですが,デプロイ周りも今自動化できているものもあれば手動デプロイしているものもあります.手動デプロイをなくすための検証もし辛いなと思っていたので環境を分離したかった感じです.

あと,副次的な効果ですが,ステージングをつくったりして環境を分離したことでよかったのが開発チームとの密な連携が取れている気がします.うちは社内システムと外向けシステムで大きく分かれているんですが,外向けは CTO が見ているので普段からコミュニケーションを取りやすいものの社内システムチームは会社の構造上アカウント分離していたころフロアが違ったりあんまり接点がなかったのですが,この機会に接点を持ってコミュニケーションを取れるようになりました.この繋がりがあったからステージング使われてないとかじゃあどうする?って話もしやすくなったのを実感したので,他チームとの連携を作るのも今のロール的に不可欠だなぁと痛感しました.

質問いただいた事

Masa さんから ssosync を使って運用しているのかという質問をいただきました.今のところ使ってなくても ID が同期されないといったトラブルに見舞われていないので使っていないのですが,ssosync の存在を知らなかったのでこの機会に試して適用を検討させていただきます.教えていただきありがとうございました🙇‍♂️

Tamakiさんからどうして SSO を絶対やりたいというツイートしたのかって質問をもらったのですが,緊張してうまく答え切れていなかったので改めて回答させてもらいます.前職でシングルサインオンのサービスを使っていてシングルサインオンの便利さやメリットを実感できていたからこそパスワードの強度や管理が人依存になっている自社では絶対パスワード認証ログインを辞めたいと思ったから SSO を入れたかったのです.

sadayoshi-tada.hatenablog.com

登壇環境

登壇環境については非常にかっこいい感じにしたかったのですが,全然映えはないですw 他の方も見てみたい...

f:id:sadayoshi_tada:20210125094448p:plain

まとめ

登壇の振り返りや質問いただいたことを書いてみました.オンラインイベントなので喋る時はもちろん1人ですが,ツイートを追ったりして反応をくださっているのほんとうにありがたかったし,内容も良いという反応があると嬉しすぎてニヤけますね...いつも見る側の立場だったので登壇させてもらえて貴重な機会をいただき本当にありがとうございます.その辺の気持ちはこのツイートにしたためました.心残りとしては Zoom ならではの発表なのに背景をダンベルまみれにしなかったことくらいですが,運営の皆さん,登壇者の皆さん,聞いてくださった皆さんとても暖かく接してくださって登壇者としても楽しくイベント参加できました! これはオフラインとしてもイベントが実現された時にも登壇できるよう日々の取り組みをやってこうと思います.改めてありがとうございました!!

元記事

元記事はこちらです.