snaqme Engineers Blog

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

胸熱! Aurora MySQL in-place upgrades 機能を使って MySQL 5.6 => 5.7 にアップグレードする

あけましておめでとうございます! SRE を担当している多田です(@tada_infra).

re:Invent 中に Aurora MySQL 5.6 から 5.7 へアップグレードすることが容易になるアップデートが出るアナウンスがあり,業務で担当しているデータベースは MySQL 5.6 なので期待していたら遂に出ました! MySQL のバージョンの追随をしていきたいと思っており,スナップショットからの復元不要かつデータベースのデータを移行したりが不要でアップグレードできるんじゃないかと期待していたので, Aurora MySQL の in-place upgrades 機能を試してみました.検証してみた内容この記事にまとめていきます.

aws.amazon.com

機能の概要

in-place upgrades 機能の特徴はバックアップによる復元でのバージョンアップではなく数クリックでアップグレードできるところが特徴です.

Instead of backing up and restoring the database to the new version, you can upgrade with just a few clicks in the Amazon RDS Management Console or by using the AWS SDK or CLI.

To upgrade to Aurora MySQL 5.7, select the "Modify" option on the AWS Management Console corresponding to the database instance you want to upgrade, choose the version of Aurora MySQL 5.7 you want to upgrade to, and proceed with the wizard. The upgrade may be applied immediately (if you select the "Apply Immediately" option), or during your next maintenance window (by default). Please note that in either case, your database cluster will be unavailable during the upgrade and your database instances will be restarted.

更にドキュメントによるとすべてのデータを新しいクラスタボリュームにコピーする必要がなく,アプリケーションの構成変更を最小限に抑えアップグレードされたクラスタのテストも少なく抑えられるとあります.また, in-place upgrades 機能の仕組みとして Aurora クラスタをシャットダウンし,トランザクションロールバックや undo purge などの未処理の操作を完了させるのも特徴です.

This technique keeps the same endpoint and other characteristics of the cluster. The upgrade is relatively fast because it doesn't require copying all your data to a new cluster volume. This stability helps to minimize any configuration changes in your applications. It also helps to reduce the amount of testing for the upgraded cluster, because the number of DB instances and their instance classes all stay the same.

The in-place upgrade mechanism involves shutting down your DB cluster while the operation takes place. Aurora performs a clean shutdown and completes outstanding operations such as transaction rollback and undo purge.

関連ドキュメント

docs.aws.amazon.com

in-place upgrades の実践

in-place upgrades を試しに使ってみます.なお,アップグレード前のバージョンは 5.6.mysql_aurora.1.22.2 になります.

f:id:sadayoshi_tada:20210113191843p:plain

Aurora クラスターのバージョン変更

Aurora クラスターのバージョン変更を行います.対象クラスターを選んで 変更 >バージョンのセクションで今回は最新のAurora(MySQL 5.7) 2.09.1 を選択して他のパラメーターをいじらずに次のページに遷移します. f:id:sadayoshi_tada:20210114091211p:plain

変更の確認画面で変更対象の確認をしますが,バージョンアップグレードに伴いクラスターパラメーターグループ,DB パラメーターグループも自動で 5.7 のものに変更になっています.すぐに適用を選択し変更を行います.変更後,少し経つとステータスが アップグレード に遷移します.

f:id:sadayoshi_tada:20210114091504p:plain f:id:sadayoshi_tada:20210114092024p:plain

自分の検証環境では約10分ほどでアップグレードが完了しました.なお,アップグレード後はバックトラックを有効化していてもアップグレード前の時間帯に戻せないとドキュメントに記述があるのでこの点注意です. f:id:sadayoshi_tada:20210114094051p:plain f:id:sadayoshi_tada:20210114102019p:plain

アップグレード中のイベント

イベントメニューよりアップグレード中のイベントを確認することができるので,進行状況を確認したい場合はイベントメニューから参照ください.また,ドキュメントにも記載があるので合わせて確認するよいでしょう.

f:id:sadayoshi_tada:20210114093525p:plain f:id:sadayoshi_tada:20210114093614p:plain

アップグレード前後のバージョン確認

in-place upgrades 実行と合わせてアップグレード前後の MySQL クライアントに接続しバージョンアップグレードの状況を確認してみましたアップグレード実行後に一度 DB コネクションがロストするが,バージョンアップグレード完了後再度クエリを投げるとバージョン情報を返すようになるところを確認できました.

mysql>
mysql> select version(); <= バージョンアップグレード前
+------------+
| version()  |
+------------+
| 5.6.10-log |
+------------+
1 row in set (0.00 sec)
mysql> select version(); <= バージョンアップグレード実行後一時的にコネクションがロスト
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql>
mysql>
mysql> select version(); <=バージョンアップ完了後再接続
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    17
Current database: *** NONE ***
+-----------+
| version() |
+-----------+
| 5.7.12    |
+-----------+
1 row in set (0.02 sec)

まとめ

まずは,Getting Started として Aurora MySQL in-place upgrades 機能を使って MySQL 5.6 から 5.7 にアップグレードしてみました.バージョンが追随できていないし,5.7 使ってみたいと思ってもこれまでのオペレーションだと再度クラスターを作り直す手間があったと思います.,実際の移行の時は計画しっかりし適用箇所を考えなければいけないと思いますが,オペレーションが簡単に行えるのでこの機能は検討して使っていければと考えてます.

元記事

元記事はこちらです.

最後に

そんなスナックミーではもりもりコードを改善し、開発していきたいバックエンドエンジニア、テックリードを募集中です。 採用の最新情報はこちらにありますので、ご興味ある方はご確認ください!

engineers.snaq.me

2020年終わりに

こんにちは スナックミー CTOの三好です @miyoshihayato 先月にスタートした弊社の技術ブログですが、まだ私は書いてなく、最低1本今年中に書きたかったので書きます。

スナックミーはどういうサービスでエンジニアの関わり方どうなっているのか長くなりすぎず書いていきます。 時間がない方は↓↓をざっとでもいいのでご覧ください

※ 適時スライドはアップデートしていきます

おやつ体験 snaq.me

snaq.meの概要を説明させてください。

f:id:snaqme-labs:20201228194557p:plain
スナックミーの概要

snaq.meがお届けするのは、お菓子という単なる「モノ」ではなく、おやつ時間、そしてワクワクしたり楽しんだりする体験、つまり『おやつ体験』です。 "毎月変わる100種以上のおやつ"から、食べきりサイズ(約20-30g)で8つお届けします。全てのおやつが人工添加物、ショートニング、白砂糖など不使用。ナチュラル素材のみからできているのが特徴です。 ジャンルはクッキー・パウンドケーキといった焼き菓子からドライフルーツ・ナッツ・米菓、羊羹・どら焼きなどの和菓子まで幅広く取り扱っています。

あらゆる声を大事にする

お客さまとのやり取りはLINEをサービス開始当初から導入しています。LINEを用いることでメールとは違い気さくに連絡をいただける方が多く、ポジティブや厳しいことなどさまざまなお声いただきます。そのような声を社内全体に共有するチャンネルが存在し、共有することでチャンネルが活性化し様々な声から施策が生まれることが多々あります。そのため、直接お客さまと関わらないのメンバーでも距離は近く感じられます。

データの活用

お客さまには届いた後におやつの評価や次回以降これを食べたいことを主張できるリクエストなどアクションをとってもらうことが可能で f:id:snaqme-labs:20201228202315p:plain お客さまの声や評価・リクエストのデータを用いて商品開発や次回お届けするおやつを決定しています。

製造から発送準備まで一貫

弊社特徴の一つなのが、このロジスティックス周り

  • 製造から発送準備までを内製化

  • 同じビル内で製造や出荷作業(ピッキング)

f:id:snaqme-labs:20201228205522p:plain 内製化し同じビル内で作業をしているので、どのようにおやつがパックされ、出荷(箱詰め)されてお客さまの手元に届くのかというこの流れを肌で感じることができます。 エンジニアは開発したシステムを利用する相手の顔が見えにくいですが、スナックミーではリアルなモノの流れを体験できます。

エンジニアとチームの関わり方

エンジニア限らずスナックミー全体は様々なチームと連携しながら事業を展開しています。 f:id:snaqme-labs:20201229210256p:plain

体験

snaq.meの購入前から購入後のマイページまで、ユーザーの”おやつ体験”に関わる様々な部分の構築を行なっています。 購入導線やおやつの好みの診断、評価・リクエストなどのページがあります。A/Bテストを通して各ページの改善や、データサイエンティストやデザイナーと共にUI/UXの向上などユーザーの体験向上を目指しています。 スナックミー全社員「永遠のβ版」という概念を持っており、お客様のフィードバックを活用しサービス改善を続けていき、製菓業界の枠組みにとらわれない挑戦を続けてまいります。

体験チームインタビューはこちら↓↓

おやつのテーマパークを一緒に作りませんか?

商品開発

今まで数千という商品を扱いユーザーの構成や行動、今までの商品に対する評価や味覚、食感の好み、リクエスト数、アンケートなどから得た知見をバイヤーやパティシエに共有し、多角的に話合いながら、新しいおやつの開発に役立てています。

商品開発チームインタビューはこちら↓↓

ほっこりおやつタイムを豊かにするデータ分析

オペレーション (ロジスティックス)

製造管理・出荷管理のソフトウェアの部分は弊社で開発しています。 例えば出荷作業に関しては、音声ピッキングを導入し、出荷効率を5~10倍アップさせることができました。 スナックミーの特徴として、

  • 毎月取り扱うおやつを数十%入れ替え (新商品含む)

  • 製造方法が異なる

  • 少量多種 (少ない量で多くの種類を製造)

などです。製造ラインは1種類1つがよくある中、スナックミーでは製造方法が異なり毎日数十種類存在する条件でもスケールできるオペレーション構築を目指していきたいと思っています。

f:id:snaqme-labs:20201229212405p:plain
出荷スペース

オペレーションチームインタビューはこちら↓↓

おやつを届けるオペレーションとエンジニアリング

CS

CSチームで考えることは

  1. 問い合わせを発生しない環境

  2. エンゲージメントを高める

この2つにあり、問い合わせを発生させない環境づくりは基本としてあるものの、エンゲージメントを高めることも意識的に行っています。 問い合わせが来るものだけを対応せず、私たちから連絡を取っていくようにしています。例えば評価内容から苦手な評価を多くつけている方には好き嫌いがないか確認し次回のボックスに活かすようにしています。

カスタマーサービスチームインタビューはこちら↓↓

様々な声を全体に浸透させていきたい

技術スタック

f:id:snaqme-labs:20201230184709j:plain

PHPからPythonへ移行中

フロントはReact × Redux、ロジスティックスはRails、基盤は AWS (一部GCP)でスナックミーを支え、開発手法はスクラムになっています。

最後に

2020年1月はエンジニアは4名だったメンバーが、2021年1月からエンジニアは8名(育休含む)に心強いメンバー増えます。 ここ1年で人数は倍になりスナックミーとしてできることが多くなってきました。しかし、成し遂げたいことは多くありメンバーは足りていません。一緒にブランドを構築し、技術力もアップしませんか? 少しでも興味もった方は気軽に連絡お待ちしております。

2021年は更なる飛躍の年に!! 外部発信も来年は精力的にやっていきます

engineers.snaq.me

www.wantedly.com

最後に

そんなスナックミーではもりもりコードを改善し、開発していきたいバックエンドエンジニア、テックリードを募集中です。 採用の最新情報はこちらにありますので、ご興味ある方はご確認ください!

engineers.snaq.me

AWS SSO と GSuite を連携した認証のフローを作ってみよう!

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

自分の会社では AWS アカウントのログイン形式がこれまでは IAM ユーザーによるアカウントに直ログインになっていたのですが,それを AWS SSO を入れてログイン方式を変更しました.ユーザー管理はデフォルトだと ID 管理が SSO で発行されるユーザーになりますが,業務で GSuite を使っているし,GSuite が IdP として使えるため,AWS SSO の IdP を GSuite で設定する場合の検証をしてみました.次の AWS ブログに手順が載っていたのでその内容に沿って検証したことをまとめます.

aws.amazon.com

aws.amazon.com

設定内容

SSO 側からサービスプロバイダー情報をコピーする

SSO 側の IdP を変更するために ID ソースを選択セクションで外部 ID プロバイダーの項目を選択します.次に,サービスプロバイダー情報のうちAWS SSO サインイン URL,AWS SSO ACS URL,AWS SSO 発行者 URLを控えておきます.

f:id:sadayoshi_tada:20201228060510p:plain f:id:sadayoshi_tada:20201228060818p:plain

GSuite でカスタム SAML アプリケーションを設定する

次に,GSuite 側の設定を行います.GSuite の管理画面に移動し,アプリ>SAMLアプリ>アプリを追加>カスタム SAML アプリの追加を選択します.カスタム SAML アプリの設定ウィザードに則って進みます.まずは,アプリ名ですがこれは任意の名前を入力して次に進みます.

f:id:sadayoshi_tada:20201228150432p:plain

次に,SSO の設定で使うため IdP メタデータをダウンロードして次に進みます. f:id:sadayoshi_tada:20201228150529p:plain

次に,サービスプロパイダの詳細設定を行います.SSO の URL を画像の箇所にコピーして転記していきます.署名付き応答にもチェックを入れて次に進み保存します

f:id:sadayoshi_tada:20201228153618p:plain

最後の属性マッピングは何もせず,完了ボタンを押します.これで GSuite の設定完了です.

f:id:sadayoshi_tada:20201228153909p:plain

SSO 側の連携設定

最後に,SSO と GSuite の連携設定を詰めていきます.はじめに GSuite のカスタム SAML アプリケーション追加設定時にダウンロードしていたメタデータをアップロードします.

f:id:sadayoshi_tada:20201228154223p:plain

アップロードが終わったら最後に確認画面です.ID ソースの変更を承認するのでACCEPTと欄に入力して ID ソースを変更します.問題なければ変更が反映されます.

f:id:sadayoshi_tada:20201228154304p:plain f:id:sadayoshi_tada:20201228154637p:plain

動作確認

最後に動作確認をします.SSO のエンドポイント URL https://XXX.awsapps.com/start にアクセスすると GSuite のユーザー認証に飛びます.

f:id:sadayoshi_tada:20201228154456p:plain f:id:sadayoshi_tada:20201228154738p:plain

ユーザー認証後,設定が問題なければ SSO のログイン後ページに遷移することを確認できました.

f:id:sadayoshi_tada:20201228154920p:plain

まとめ

AWS SSO の IdP として GSuite を設定する検証を行ったのでその内容をまとめました.自分が働く会社では GSuite が業務の中心にありその ID も使うので IdP として投入できれば,入社・退社の手続きでアカウントを消すだけで業務アプリケーションのログイン情報も消せてよく,IAM ユーザーによるログイン管理からも開放されるので効果を感じられました.同様の設定を考えられている方の何か参考になれば幸いです.

関連記事

labs.snaq.me

元記事

元記事はこちらです.

最後に

そんなスナックミーではもりもりコードを改善し、開発していきたいバックエンドエンジニア、テックリードを募集中です。 採用の最新情報はこちらにありますので、ご興味ある方はご確認ください!

engineers.snaq.me

AWS Client VPN のユーザー認証を Active Directory 認証で行う

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

AWS Client VPN の相互認証を検証した時の課題が VPN 接続ログに誰が VPN を使っているかが記録されてなかったことです.ユーザー認証の仕組みは Active Directory 認証と SAML 認証が用意されているのですが,この記事では Active Directory 認証を試した内容をまとめていきます.

docs.aws.amazon.com

検証シナリオ

シナリオとしては,これまで ACM のサーバー及びクライアント証明書による相互認証だったところを Active Directory 認証の基盤として Simple AD を使って認証するように変更しています.Simple AD を新規に作り,その中で認証するユーザーを作成・管理するような形に変更します.それ以外の設定は変わりません.

f:id:sadayoshi_tada:20201228002910p:plain

設定内容

ユーザー認証設定としてやるのは①Simple AD をプライベートサブネットに作成およびユーザーの作成,②ユーザー認証でエンドポイントの再作成および Client VPN 各種再設定です.

①Simple AD をプライベートサブネットに作成およびユーザーの作成

まず,ユーザー認証基盤である Simple AD の作成とユーザーの作成を行います.ただ,この記事では Client VPN の設定部分にフォーカスするようにしたいため,Simple AD の作成やユーザー作成部分は公式ドキュメントの説明に譲り,割愛します.

docs.aws.amazon.com

②ユーザー認証でエンドポイントの再作成および Client VPN 各種再設定

Client VPN エンドポイントを再作成していきます.変わるのは大きく2カ所です.1つは認証オプションをユーザー認証に設定し,①で作成した Simple AD を指定することと,DNS サーバーの箇所に Simple AD の DNS サーバーの IP アドレス2つを記載することが変わりますが,それ以外は初回の記事と同じ設定で定義しました.また,受信の認証ルールおよびルートテーブルも初回と二回目の記事と同様の設定に行いました.

f:id:sadayoshi_tada:20201228001612p:plain f:id:sadayoshi_tada:20201228001739p:plain

動作確認

エンドポイントの設定が完了後クライアント設定ファイルをダウンロードして VPN クライアントアプリのプロファイルを追加しました.接続を試みるとユーザー認証画面が表示されます.Simple AD の Administrator で認証してみます.

f:id:sadayoshi_tada:20201228002119p:plain

認証が成功し,VPN 接続のログを確認してみたところユーザー名の欄に Administrator が表示されているので意図した通りの設定ができました.

f:id:sadayoshi_tada:20201228002330p:plain

まとめ

Client VPN のユーザー認証方式として Active Directory の認証パターンを試したので検証内容をまとめました.Active Directory 認証パターンも試したのですが,もう1つの SAML 認証パターンも試したいと思っており,AWS SSO との連携をしてみたいと考えているのでその内容は次回以降の記事に書いていきます!

関連記事

labs.snaq.me

labs.snaq.me

元記事

元記事はこちらです.

最後に

そんなスナックミーではもりもりコードを改善し、開発していきたいバックエンドエンジニア、テックリードを募集中です。 採用の最新情報はこちらにありますので、ご興味ある方はご確認ください!

engineers.snaq.me

AWS Client VPN の IP アドレスを固定化してインターネットと通信する

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

AWS Client VPN 検証の続きです.前回の記事でプライベートサブネットの EC2 への VPN 接続が可能になりました.次に,VPN を繋いだ IP アドレスで業務システムへのアクセス制限をしたいといった要件で検証した内容です.

labs.snaq.me

検証シナリオ

Client VPN が接続できるネットワークと分離した社内のシステム用のネットワークがあると仮定します.要件として ELB + EC2 の業務システムにアクセスできる IP を絞りたいというものがあります.そこで,Client VPN に繋いでインターネットと通信する際は NAT Gateway を経由させることで IP アドレスを固定化します.

f:id:sadayoshi_tada:20201227185255p:plain

パブリックサブネットに Client VPN を関連づけることでインターネットに通信を出すことができますが,接続時にネットワークインターフェースが変わってグローバル IP アドレスも変わってしまうため固定化するために NAT Gateway を使っています.

f:id:sadayoshi_tada:20201227200427p:plainf:id:sadayoshi_tada:20201227200437p:plain

設定内容

前回記事内容に追加する形で設定を行う場合を想定します.やるのは①NAT Gateway をパブリックサブネットに作ってプライベートサブネットのルートテーブルに関連づける,②ルートテーブルと受信の承認ルールの変更する

①NAT Gateway をパブリックサブネットに作ってプライベートサブネットのルートテーブルに関連づける

NAT Gateway を作成し,パブリックサブネットに作ります.作成後,パブリックサブネットが使っているルートテーブルに関連づけます.設定の詳細は下記の解説ページに譲り割愛します.

aws.amazon.com

②ルートテーブルと受信の承認ルールの変更する

受信の承認ルールに0.0.0.0/0 の許可を追加します.ルートテーブルにも同様に0.0.0.0/0 の経路を追加します.

f:id:sadayoshi_tada:20201227203227p:plain

f:id:sadayoshi_tada:20201227203454p:plain

動作確認

NAT Gateway を経由できているのであれば,インターネットに接続できて EIP のアドレスで通信するはずです.検証用に NAT Gateway には 3.113.152.210 を EIP を設定しているので, 使用中の IP アドレス確認をしてみます.

意図通りの設定ができていることを確認できました.

f:id:sadayoshi_tada:20201227203856p:plain

まとめ

今回は,Client VPN を使いつつ IP アドレスの固定化を行ってみました.相互認証での検証は以上になるのですが,相互認証方式だと1つ課題があります.それは接続のログにユーザー名が表示されないことです.この課題を次の記事でユーザー認証方式に切り替えた内容でまとめます.

f:id:sadayoshi_tada:20201227204212p:plain

元記事

元記事はこちらです.

最後に

そんなスナックミーではもりもりコードを改善し、開発していきたいバックエンドエンジニア、テックリードを募集中です。 採用の最新情報はこちらにありますので、ご興味ある方はご確認ください!

engineers.snaq.me

プライベートサブネットのサーバー接続をするために AWS Client VPN を使ってみる

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

リモートワークが広がる中で AWS Client VPN を使って各種業務システムへの接続を検証する必要があり,AWS Client VPN を検証したので何記事かに分けて検証した内容をまとめます.この記事で Get Started な内容を書いていきます.既に同様の内容の記事は多くあるのですが,やった内容整理するために記事を書きます.

AWS Client VPN とは

AWS Client VPN は下記引用文のようなサービスです.Client VPN 登場前はインターネット VPN のためにサーバーを用意する必要がありましたが,それが無くなりマネージドサービスして提供されているためスピーディーに使えてかつサーバー運用不要なところがいいなと思っています.

AWS Client VPN は、AWS リソースやオンプレミスネットワーク内のリソースに安全にアクセスできるようにする、クライアントベースのマネージド VPN サービスです。クライアント VPN を使用すると、OpenVPN ベースの VPN クライアントを使用して、どこからでもリソースにアクセスできます。

docs.aws.amazon.com

課金体系

Client VPN の課金対象となるのが下記の2項目です.

課金項目 課金額
AWS Client VPN エンドポイントアソシエーション $0.15/時間
AWS Client VPN 接続 $0.05/時

aws.amazon.com

AWS Client VPN を使ってプライベートネットワークにある EC2 に接続する

検証のシナリオとしてプライベートサブネットにある EC2 に Client VPN を使って接続してみます.

f:id:sadayoshi_tada:20201227143437p:plain

Client VPN では認証方式が3つあり,AD 認証,SAML 認証,相互認証があります.今回は相互認証,サーバーとクライアント間で証明書認証を行います.証明書は ACM に登録しておきます.

相互認証では、クライアント VPN は証明書を使用してクライアントとサーバー間の認証を実行します。証明書とは、認証機関 (CA) によって発行された識別用デジタル形式です。クライアントがクライアント VPN エンドポイントに接続を試みると、サーバーはクライアント証明書を使用してクライアントを認証します。サーバー証明書とキー、および少なくとも 1 つのクライアント証明書とキーを作成する必要があります。

サーバーおよびクライアント証明書とキーの生成

サーバーおよびクライアント証明書とキーの作成を行いますが,ドキュメントに記載のフローで対応してきます.キーの作成には easy-rsa を使用します.

docs.aws.amazon.com

$ git clone https://github.com/OpenVPN/easy-rsa.git
$ cd easy-rsa/easyrsa3
$ ./easyrsa init-pki #PKI 環境を初期化
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /XXXX/XXXX/easy-rsa/easyrsa3/pki

$ ./easyrsa build-ca nopass #新しい認証機関 (CA) を構築
Using SSL: openssl LibreSSL 2.8.3
Generating RSA private key, 2048 bit long modulus
......................................................................................+++
..............................................+++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:awsclient-vpn #任意の名前を入力

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/XXXX/XXXX/easy-rsa/easyrsa3/pki/ca.crt


$ ./easyrsa build-server-full server nopass #
Using SSL: openssl LibreSSL 2.8.3
Generating a 2048 bit RSA private key
................................................+++
.............................................................+++
writing new private key to '/XXXX/XXXX/easy-rsa/easyrsa3/pki/easy-rsa-12050.LbZL9a/tmp.B8ySWj'
-----
Using configuration from /XXXX/XXXX/easy-rsa/easyrsa3/pki/easy-rsa-12050.LbZL9a/tmp.EXwFe7
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'server'
Certificate is to be certified until Mar 26 06:03:31 2023 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

$ ./easyrsa build-client-full client1.domain.tld nopass
Using SSL: openssl LibreSSL 2.8.3
Generating a 2048 bit RSA private key
....+++
............................+++
writing new private key to '/XXXX/XXXX/easy-rsa/easyrsa3/pki/easy-rsa-10663.vj9o3i/tmp.7GLYfD'
-----
Using configuration from /XXXX/XXXX/easy-rsa/easyrsa3/pki/easy-rsa-10663.vj9o3i/tmp.TXc5fX
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'client1.domain.tld'
Certificate is to be certified until Mar 26 04:03:38 2023 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

# 専用のカスタムフォルダーにサーバー及びクライアント証明書をコピーする
$ mkdir ~/client_vpn/
$ cp pki/ca.crt ~/client_vpn/
$ cp pki/issued/server.crt ~/client_vpn/
$ cp pki/private/server.key ~/client_vpn/
$ cp pki/issued/client1.domain.tld.crt ~/client_vpn
$ cp pki/private/client1.domain.tld.key ~/client_vpn/
$ cd ~/client_vpn/

証明書の ACM へのインポート

作成した証明書を ACM にインポートします.サーバー証明書とクライアント証明書をインポートします.コマンドがうまくいかない場合は画面から直接インポートでも証明書の登録可能です.

$ aws acm import-certificate --certificate fileb://server.crt --private-key fileb://server.key --certificate-chain fileb://ca.crt --region ap-northeast-1
$ aws acm import-certificate --certificate fileb://client1.domain.tld.crt --private-key fileb://client1.domain.tld.key --certificate-chain fileb://ca.crt --region ap-northeast-1

f:id:sadayoshi_tada:20201227091556p:plain

AWS Client VPN 設定を行う

Client VPN を使うための設定を行います.やるのは①クライアント VPN エンドポイント作成,②クライアントの VPN 接続の有効化,③クライアントのネットワークへのアクセスの承認です.

①クライアント VPN エンドポイント作成

クライアントが Client VPN との接続を確立するエンドポイントを作成します.IPアドレスの CIDR は /12~/22 の範囲で指定が必要です.検証用途のため一番小さいサイズで指定しています.また,ACM にインポートしたサーバー及びクライアント証明書を指定します.

IP アドレス範囲は、ターゲットネットワークまたはクライアント VPN エンドポイントに関連するいずれかのルートと重複できません。クライアント CIDR は、/12~/22 の範囲のブロックサイズが必要で、VPC CIDR またはルートテーブル内のその他のルートと重複できません。クライアント VPN エンドポイントの作成後にクライアント CIDR を変更することはできません。

f:id:sadayoshi_tada:20201227153102p:plain

残りとして関連するエンドポイントを紐付ける VPC とセキュリティグループを指定し,それ以外はデフォルト値でエンドポイントの作成を行います.

f:id:sadayoshi_tada:20201227153131p:plain

②クライアントの VPN 接続の有効化

次に,クライアントの VPN 接続の有効化を行います.エンドポイントと関連づけるサブネットを指定します.これでエンドポイントが有効化ステータスに遷移したり,ルートテーブルへの設定変更やセキュリティグループの関連付けが行われます.

f:id:sadayoshi_tada:20201227154839p:plain

クライアント VPN エンドポイントの状態が available に変わります。これで、クライアントは VPN 接続を確立できるようになりましたが、認証ルールを追加するまで VPC 内のリソースにアクセスすることはできません。

VPC のローカルルートは、クライアント VPN エンドポイントルートテーブルに自動的に追加されます。

VPC のデフォルトのセキュリティグループが、サブネットの関連付けに自動的に適用されます。

しばらくエンドポイント有効化までに時間を要するので待ちます.

f:id:sadayoshi_tada:20201227154155p:plain

③クライアントのネットワークへのアクセスの承認

そして,クライアントのネットワークへのアクセスの承認を行います.クライアントがアクセスできるサブネットの承認ルールを作成します.ユーザーは誰でもつなげるようにしておき,接続できるネットワークは EC2 がいる VPC の CIDR ブロックを指定しています.

f:id:sadayoshi_tada:20201227155851p:plain

VPN クライアント端末のセットアップ

Client VPN の設定は以上で,次に VPN クライアント側の設定をします.やるのは①クライアントアプリのインストール,②Client VPN 設定の取り込みです.

①クライアントアプリのインストール

AWS から専用のクライアントアプリが Windows/Mac それぞれで提供されているので下記のサイトからダウンロード,インストールします.

aws.amazon.com

自分は Mac なのでアプリケーションアイコンとして次のものができていました.

f:id:sadayoshi_tada:20201227160402p:plain

②Client VPN 設定の取り込み

次に,Client VPN 設定の取り込みを行います.Client VPN 画面から クライアント設定のダウンロード ボタンから設定ファイルをダウンロードすると,downloaded-client-config.ovpn というファイルが保存されます.ダウンロードしたファイルをエディターで開き,末尾にクライアント証明書の情報を転記します.

<cert>
Contents of client certificate (.crt) file
</cert>

<key>
Contents of private key (.key) file
</key>

VPN クライアントに設定ファイルを取り込むためにはプロファイルを管理 > プロファイルを追加 していきます.接続名は任意のもの(今回は test というプロファイル名にしました)にし,VPN 設定ファイルはダウンロードした設定ファイルを指定します.これで AWS との接続する準備が整いました.

f:id:sadayoshi_tada:20201227160728p:plain

サーバーへの接続テスト

いよいよプライベートサブネットのサーバーに繋いでみます.サーバーの IP アドレスは XXX.XXX.2.163になります.VPN を経由して SSH で繋いでみましょう.VPN 接続後に端末の IP アドレスを確認すると Client VPN エンドポイントに割り当てたネットワークのアドレスが振られていました.

f:id:sadayoshi_tada:20201227161341p:plain

% ifconfig
~中略~
utun2: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
    inet XXX.XXX.0.2 --> XXX.XXX.0.2 netmask 0xffffffe0

そして,対象のサーバーにも SSH できました!

 % ssh -i .ssh/XXX.pem XXX@XXX.XXX.2.163

Last login: Mon Dec 21 07:04:45 2020 from XXX.XXX.2.45
XXX@ip-XXX-XXX-2-163:~$
XXX@ip-XXX-XXX-2-163:~$ exit

まとめ

まずは Client VPN をつかってプライベートサブネットの EC2 に接続することをやりました.次は Client VPN をプライベートサブネットにある EC2 にもつなぎつつ他システムで IP アドレスを制御するためグローバル IP アドレスを付与しつつ Client VPN を使う検証を行った内容をまとめます.

元記事

元記事はこちらです.

最後に

そんなスナックミーではもりもりコードを改善し、開発していきたいバックエンドエンジニア、テックリードを募集中です。 採用の最新情報はこちらにありますので、ご興味ある方はご確認ください!

engineers.snaq.me

microCMS + Nuxt.js + Vue.js のコンテンツを GitHub Actions でビルド&デプロイする

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

microCMS + Nuxt.js + Vue.js のコンテンツを GitHub Actions を使ってビルド,S3 にコンテンツを配備する設定を行いました.また,コンテンツが更新された時にも自動でデプロイされるような設定も行ったので振り返り目的で各設定についてまとめていきます.

GitHub Actions の定義

まず,GitHub Actions の定義部分です.やっている処理は S3 にアップロードするためのアクセスキーとシークレットアクセスキーを設定 -> ビルド -> S3 にコンテンツを同期しています.また,アクセスキーとシークレットアクセスキー,S3 へのパスを GitHub Secrets に設定しています.これで GitHub の特定ブランチにコードがプッシュされたら自動でビルド,S3 にコンテンツ配備されるよう設定できました.

jobs:
    build:
        name: Build & Deploy
        runs-on: ubuntu-latest

        steps:
            - name: Checkout
              uses: actions/checkout@v2
            
            - name: Configure AWS credentials
              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: ap-northeast-1

            - name: Build
              run: |
                yarn install 
                yarn build
                yarn generate
            - name:  Contents sync to s3
              run: |
                aws s3 sync [contents path] ${{ secrets.S3_PATH }} 

参考情報

docs.github.com

microCMS 設定部分

次に,microCMS 設定です.microCMS のコンテンツを更新が走った時に自動でGitHub Actions が自動ビルド,デプロイするように設定していきます.管理画面の API 設定 > Webhook > GitHub Actions を選択し,下記の画面の設定を行いました.

f:id:sadayoshi_tada:20201218113117p:plain

GitHub Actions 定義

microCMS 側の設定後 GitHub Actions 側も設定を追加しています.GitHub Actions の定義でrepository_dispatch を指定して microCMS の記事が更新,削除されたりした時 update_post イベントが発行されてくるので そのイベントをトリガーに GitHub Actions が動くように設定しました.これで記事を更新したら自動でビルド,デプロイするようになりました.

on:
~中略~
    repository_dispatch:
      types: [update_post]

参考情報

docs.github.com

まとめ

microCMS + Nuxt.js + Vue.js のコンテンツを GitHub Actions を使ってビルド,S3 にコンテンツを配備するための設定を行ったのでその内容を振り返ってまとめました.設定自体は比較的簡単にできるけれど自動ビルド,デプロイされるのは非常にありがたいです.同様の設定する方の参考になれば嬉しいです.

元記事

元記事はこちらです.

最後に

そんなスナックミーではもりもりコードを改善し、開発していきたいバックエンドエンジニア、テックリードを募集中です。 採用の最新情報はこちらにありますので、ご興味ある方はご確認ください!

engineers.snaq.me