Go(Echo)で作成したAPIをECSにデプロイしてみよう
はじめに
pirotyyyです。
先日、「ECS使ってみたいなー」って思ったところにこんな記事を見つけました。
こちらの記事では、ECSについて基本的な内容およびそれを理解するための周辺知識(Dockerについてなど)までまとまっており、私にとって需要MAXな記事でした。
その記事を読み終えたところで「Goで作成したAPIをECSにデプロイする」ということをテーマに、私個人のアウトプットとして本記事を書いていこうと思います。
前提知識
ECS(Elastic Container Service)とは
AWSが提供するコンテナの実行環境です。
ただ実行するだけでなく、サーバの設定やメンテナンスなどをAWSが全てやってくれるサービスです。
また複数のコンテナの管理もAWSがやってくれます。
ECR(Elastic Container Registry)とは
Dockerのイメージを保存してくれるサービスです。
ECSでは、ここに保存されたイメージを使ってコンテナを作成し実行します。
実装
それでは、これからECSにGoのAPIをデプロイしそのAPIから「Hello World」を取得するまでやっていきます。
1. ECRにリポジトリを作成する
まず、ECRにイメージを保存するためのリポジトリを作成します。
以下のような設定でいきます。
2. ローカルでイメージを作成し、ECRのリポジトリにpushする
Echoを用いて簡単なAPIを作成します。コードは以下の通りです。
package main
import (
"net/http"
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.JSON(http.StatusOK, "Hello World")
})
e.Logger.Fatal(e.Start(":8080"))
}
FROM golang:1.22-alpine
WORKDIR /app
COPY . .
RUN go mod download
RUN go build -o main main.go
EXPOSE 8080
CMD go run main.go
ローカルでビルドして以下のコマンドを実行するとAPIが起動します。
docker run -p 8080:8080 {image_id}
試しにcurlコマンドでAPIを叩いてみると、
❯ curl http://localhost:8080
"Hello World"
となります。APIの動作は問題ないですね。
準備はできたので作成したイメージをECRにpushしていきます。
aws-cliのセットアップ
セットアップ方法については以下の記事が参考になると思います。
- Windowsの方
- Macの方
まず、先ほど作成したECRにイメージをpushするための認証を行います。
aws ecr get-login-password | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<region>.amazonaws.com
上記のコマンドを作成し、以下の出力が得られたら成功です。
Login Succeeded
次に、ローカルのイメージにタグをつけます。
docker tag go-api-test-ecr:latest <aws-account-id>.dkr.ecr.<region>.amazonaws.com:1.0.0
最後に、pushします。
docker push docker push <aws-account-id>.dkr.ecr.<region>.amazonaws.com:1.0.0
AWSコンソールでECRの画面を開き、go-api-ecr-test
リポジトリの中を見てみると、しっかり先ほど作成したイメージが格納されていることがわかりますね!
3. ECSのセットアップ
ECRにイメージを格納できたところで、今度はECSのセットアップを行なっていきます。
クラスターの作成
ECSにおけるクラスターとは、コンテナ化されたアプリケーションを実行するための論理的なグループで、クラスターでは、実行環境などの設定を行います。
ECSの画面に移動し、クラスターのタブから「クラスターの作成」をクリックしてください。
今回は以下の設定でいきます。(添付画像以外の部分はデフォルトでOK!)
一覧ページに戻って、「go-api-cluster」という名前のクラスターが作成されていれば成功です!
タスク定義
次にタスク定義というものを行なっていきます。
ECSにおけるタスクとは、コンテナ化されたアプリケーションを実行する最小単位であり、タスク定義によって、実行するコンテナのイメージ、使用するCPUやメモリの量などを設定します。
今回は以下のような設定にします。
作成ボタンを押して、バナーで「正常に作成されました」と出ていたらOKです!
サービスの作成
次にサービスを作成していきます。
サービスは、タスク定義に基づいて、特定のタスクの実行と管理を自動化するECSの機能です。
例えば、サービスの設定では常に実行しておくタスクの数を指定することができます。タスクの数を指定しておくことで、何かしらの障害であるタスクが落ちてしまっても、AWS側で新たなタスクを作成してくれます。コンテナオーケストレーションの機能が働いてるってことですね。
今回は以下の設定にします。(画像以外の場所はデフォルトでOKです。)
作成ボタンを押して、api-service
のログで、http server started on [::]:8080
というのが出ていたら、成功です!!
4. VPCのセキュリティグループの設定
先ほどの節で、EchoのAPIが動いていることを確認できました。「あれてことはもうAPI叩けるんじゃね?」ってなるかもしれませんが、あと1つ重要な設定を行います。
(私はこの設定をしておらず、どん詰まりしてました。。)
重要な設定とは、VPCのセキュリティグループにおけるインバウンドルールの設定です。
急に新しい単語が出てきたので少しだけ解説します。
VPCとは
VPCとはVirtual Private Cloudの略で、AWS上に作成できるプライベート仮想ネットワーク空間です。
インバウンドルールとは
インバウンドとは、ネットワークにおいて外部から内部への通信方向を表しています。すなわちインバウンドルールとは、外部からのどのような通信を許可するかを決めたものです。
VPCについて詳しく知りたい方は、以下の記事が非常に参考になるので見てみてください。
ということで、これから「プロトコルTCPでポート8080」への通信を許可する設定をしていきます。
「サービス>api-service>設定とネットワーク>ネットワーク設定」からセキュリティグループのリンクをクリックします。 セキュリティグループのページに遷移し、「インバウンドのルールの編集」というボタンをクリックし、以下のような設定を追加します。
これでVPCの設定は完了です!
動作確認
「サービス>api-service>タスク」からパブリックIPを確認し、GETリクエストを送ります。
具体的には以下のコマンドを打ちます。
curl http://{Public IP}:8080/
実行して、"Hello World"
が返ってきたらOKです!
まとめ
お疲れ様です!見事「Goで作成したAPIをECSにデプロイする」ということをテーマに、実際にAPIを叩いて"Hello World"
を取得することができました。
大枠は掴めたので、これからは以下のことに挑戦してみようと思います!
- Github Actionsを使って、GoのAPIをECSにデプロイするCIを組む
- より実践的なVPCを構築し、データベースとセキュアな通信を行うAPIをデプロイ
- HTTPS化
エンジニアとして初めてこういった技術記事を書いてみました。
記事を書くことで自分の学んだことを体系的にまとめることで理解をさらに深めることができてめっちゃいいなと思いました。これからも何か学んだら記事として残していきたいなと思います。
本記事に関して、内容にミスなどございましたら遠慮なくご指摘ください!!
参考サイト
Discussion