AWS
AWS Load Balancerを使用する際、常に405(Method Not Allowed)が出る場合
会社のAPIサーバでウェブフック関連のAPIを作成することになり、POSTリクエストを受け取るウェブフックエンドポイントを生成しました。 しかし、確かにリクエストを送信するサーバでは正常にPOSTでリクエストを送っているのに、受信するサーバのログでは405(Method Not Allowed)が表示されました。 原因 AWS Load Balancerを使用する際、HTTPリクエストをHTTPSにリダイレクトする機能があります。 一般的には上記のように設定されますが、この場合301(Moved Permanently)でリダイレクトを行うため、HTTPでPOSTリクエストを送るとHTTPSにリダイレクトされる際にGETリクエストに変わります。 サーバはLoad Balancerの背後にあるため、GETリクエストを受け取るエンドポイントがないので405(Method Not Allowed)が表示されました。 これを図で示すと以下のようになります。 リダイレクトの原理 通常のリダイレクトは、クライアント(ウェブブラウザなど)がサーバから301(Moved Permanently)のようなリダイレクト応答を受け取ると、クライアントはリダイレクト応答に含まれるLocationヘッダのアドレスに再リクエストを行います。 リダイレクトの場合、以前送信したRequest、HTTP Methodなどの情報を通常保持していないため、GETリクエストおよび以前送信したBodyを失った状態で再リクエストを行います。 解決方法 解決方法は非常に簡単です。リダイレクトされないように最初からHTTPSでリクエストを送れば良いのです。 Load Balancerが提供するこの機能は、staticなページを受け渡す際(例:text/htmlのようなcontent-typeを持つリクエスト)にHTTPSプロトコルを通じて受信するようリダイレクトするために使用するものであり、REST APIサーバのような場合は、URLにhttpではなくhttpsを明記してリクエストを送るようにすればよいです。 参考文献 https://webstone.tistory.com/65
2023年11月23日
AWS ECSサービスをGithub Actionsで自動的に開始および終了する
AWS ECSでデプロイしたPlog(「開発者のためのブログ制作プロジェクト」)を終了するにあたり、サーバーメンテナンスの費用を可変的にコントロールしたいと思いました。 (勉強目的で始めたものであり、お金を稼ぐために維持しているサービスではないので… 節約しないといけないですね…) ECSの費用は大したものではありませんが、それでも無駄に維持する必要はないと考えました。ただ、チームメンバーがいつでも転職や就職時にポートフォリオとして活用できるように、APIサーバーを上げたり下げたりすることを企画しようと思います。 ECSサービスの終了はどうするのか? 実は非常に簡単です。ECSサービスの希望するタスク数を0に設定すればよいのです。逆に開始する場合は、希望するタスク数を希望するコンテナ数に設定すればよいのです。 注意すべき点は、この方法が決してデプロイする方法を意味するわけではないということです。すでに生成されたコンテナを終了し、再起動することを意味します。 AWS CLI 以前はAWS CLIのコマンドを自動化して使用しようとしていました。方法もわかっていましたが、結局はGithub Actionを利用することにしました。 理由は次の通りです。 フロントチームメンバーはAWSにあまり慣れていませんでした。 AWSクライアントのコマンドを使用するにはAWSアクセスキーとシークレットキーを使用する必要がありますが、これらをチームメンバー間で共有して使用することはあまり優雅に見えませんでした。 手順 AWSアクセスキーIDとAWSシークレットアクセスキーをチームメンバー間で共有した後、AWS CLIをインストールします。 AWS Configureを介して、アクセスキーとシークレットキーを入力して設定を完了させます。 $ aws configure > AWS Access Key ID [None]: {AWS_ACCESS_KEY_ID} > AWS Secret Access Key [None]: {AWS_SECRET_ACCESS_KEY} > Default region name [None]: {AWS_REGION} > Default output format [None]: {AWS_OUTPUT_FORMAT} AWSクライアントを介してECSサービスを開始および終了します。 $ aws ecs update-service --cluster plog-cluster --service plog-service --desired-count 0 # サービス終了 $ aws ecs update-service --cluster plog-cluster --service plog-service --desired-count 希望のタスク数 # サービス開始 Github Actions Github ActionsはGithubが提供するCI/CDサービスです。Githubが提供するさまざまなアクションを通じてCI/CDを構成することができます。
2023年10月18日
AWS Secrets Managerを活用してローカルシークレットをうまく管理する方法
会社でローカルにシークレットを共有するうちに、Slackやカカオトークのようなメッセンジャーを通じてシークレットをやり取りすることがしばしばある。 理由はしばしば次のようになる 変更事項に対処するために既存のローカルシークレットを更新しなければならない場合 新規入社時に初期シークレットを設定しなければならない場合 このような方法は、メッセンジャーという共有チャンネルにシークレットに関する機密情報が残ったり、さまざまなセキュリティ面で良くないと感じた。 AWS Secret Generatorそこで作った。Golangで制作した簡単なCLIツールで、AWS Secrets Managerに保管されているシークレットを簡単なCLIを通じて取り出し、ローカルにファイルの形で取り込むことができる。 使い方 準備 AWS Access Key ID、AWS Secret Access Keyは事前に共有されていることを仮定する。 AWS Secrets Managerセットアップ まず、Secrets Managerに入り、設定をセットアップする。該当欄で「新しいシークレットを保存」を選択。 シークレットタイプを選択する。筆者は複数の設定が含まれる複合的な形のconfigをセットアップするシナリオを考慮して他のタイプのシークレットを設定した。(AWSに関連するサービスの特定のシークレットを設定したい場合は、他のタイプのシークレットを選択しても良い。) プレーンテキスト形式をタップし、現在使用しているローカルシークレットのファイルをコピーアンドペーストして生成する。 キー・バリュー・ペアを使用してJSON形式で強制する方法ももちろん可能だ。 筆者はyaml形式で「hello: world」のような単純なシークレットを使うと仮定した。 実際にconfigをセットアップする際にはローカルで動作可能なconfigをセットアップする必要がある。 シークレット名、説明を入力する。シークレット名はその後のプロセスでcliプログラムで選択するキー・バリューになるため、よく記憶しておく。 設定したシークレットを定期的に他のシークレットに置き換えるかどうかに関する部分。筆者は別途この機能を使用しないと仮定したため、設定しなかった。 次のステップで保存ボタンを押すとシークレットが生成される。 全体的なCLIインストールは次のリポジトリの説明に従う。 https://github.com/YangTaeyoung/aws-secret-gen aws-secret-genを使用する コマンドラインに次のように入力する。 $ aws-secret-gen -o test-config.yaml{保存するファイルパス} すると次にAWS Access Key IDとSecret Access Key、Regionを設定する画面が表示される。 事前に準備したキーとリージョンを入力する。 > Enter AWS Access Key ID: {準備したAWS Access Key ID} > Secret AWS Secret Access Key: {準備したAWS Secret Access Key} > Enter AWS Region: {AWS Regionキー: ソウルの場合ap-northeast-2} 以降、シークレットリストが表示される。自身が生成したシークレットを取り込む。 Use the arrow keys to navigate: ↓ ↑ → ← ? Select Secret: ... ▸ test-config エンターを押すと自身が設定したパスにシークレットがうまく生成されたことを確認できる。 $ cat ./test-config.yaml > hello: world
2023年9月23日
AWS Secrets Managerを使用してConfigファイルをAWSで管理する
導入 気にかけていなかったが、毎回不便だった部分があります。サーバーで使用するすべてのシークレットをconfig.yamlというファイル内で保管していたのです。 「果たしてGithubでこのようにソースで保管してもよいのだろうか?」と疑問に思いました。 Githubでも、リポジトリで使用するさまざまなシークレットを管理できるようにGithub Secrets機能を提供していますが、何か無防備に露出された感じを受けました。 最初の考え Github Secrets ビルド時に必要なすべての変数をGithubが提供するSecrets機能を活用してすべて隠してみるのはどうかと考えたこともあります。 ただし、この方法は特定の変数を隠すのには有利かもしれませんが、後でこの変数がどのようなときに注入されるのか把握しにくく、Githubという限られた環境内でしか動作しないため、もう少し一般的に使用する必要があるように思われました。 目的 さまざまな考えをしているうちに、シークレットを管理するツールとして以下のように3つ程度の基準を設けました。 他のチームメンバーが見てすぐに使えるように敷居が低く、使いやすくなければならない。 複数のサービスで使用できるように一般的にアクセス可能な方式を提供する必要がある。 オーバーエンジニアリングを避け、最低限の変更でconfigを読み込んで使用できなければならない。 ChatGPT 知識が不足していました。まずはどのような代案があるのかを探してみる必要がありました。以前であればGoogleに助けを求めていたでしょうが、探索に良いツールであるChatGPTを活用してみました。 Vaultや他のクラウドサービスが提供するキー管理システムが目を引きます。Acloset内部ではAWSが提供するサービスを大量に使用しているため、何かAWSと相性が良いAWS Secrets Managerに注目することにしました。 概略と詳細機能を知ることができました。 AWS Secrets Manager 悩んでいると開発が遅れるだけ!さっそく使ってみました。 ステップ 単純なキー・バリューの保存だけでなく、AWS RDS情報や他のデータベース情報までアドレスとポート情報を入力するとシークレットを構成できました。 まず現在のサービスで使用中のconfig.yamlを暗号化することが目的なので、他のタイプのセキュリティパスワードを選んでみました。 上記のようにAWSが作成したキー、バリューペアでもパスワードを生成することができますが、config.yaml全体を入力したいため、プレーンテキストをクリックしてみます。 デフォルトが{}として入力されているため、jsonフォーマットのみ可能と考えられますが、テキストであれば何でも可能なので、私は私たちのサーバーのconfig.yamlをすべて移してみました。 その後、セキュリティパスワードについて設定することができます。特にセキュリティパスワード名はAWSクライアントで該当するシークレットにアクセスするキーになるので、賢明につけることが望ましいです。私はsomeapp/config/devと入力してみました。 最後の段階です。現在は特別にローテーション設定をしていませんが、今後ローテーション環境やローテーションが必要なキーがあるときに積極的に活用すべきだと思わされる機能が見えます。特別に設定せず、保存をクリックして保存します。
2023年3月1日