まさなみブログ

主にweb系開発の記事を適当に書いてます。

M1 Macで ECSにSpring bootのREST APIをデプロイしようとしたけど失敗した

環境

macOS Big Sur M1

デプロイするサンプルアプリ

/greetinghello worldを返すだけのSpring-bootのREST API

github.com

ECS Fageteへのデプロイ

copilotを使ってデプロイする

AWS CLIが必要なので先にインストール

# homebrewでインストール
$ brew install awscli
# 確認
$ aws --version
aws-cli/2.3.5 Python/3.9.7 Darwin/20.6.0 source/arm64 prompt/off

AWS CLIの初期設定

$ aws configure
AWS Access Key ID [None]: アクセスキー
AWS Secret Access Key [None]: シークレットアクセスキー
Default region name [None]: リージョン
Default output format [None]:

Copilotインストール

$ brew install aws/tap/copilot-cli
# 確認
$ copilot -v
copilot version: v1.12.0

Copilotで環境作成

$ copilot init
What would you like to name your application? [? for help] greeting-app #デプロイするアプリケーション名を入力

Application name: greeting-app

  Which workload type best represents your architecture?  [Use arrows to move, type to filter, ? for more help] # 構築したい構成を選びます。
    Request-Driven Web Service  (App Runner).
    > Load Balanced Web Service   (Internet to ECS on Fargate)
    Backend Service             (ECS on Fargate)
    Worker Service              (Events to SQS to ECS on Fargate)
    Scheduled Job
# LB込みでバックエンドサービスをデプロイしたいので Load Balanced Web Serviceを選択

Which Dockerfile would you like to use for greeting-app?  [Use arrows to move, type to filter, ? for more help] # Dockerfileを選択
  > greeting/Dockerfile

 Which port do you want customer traffic sent to? [? for help] (80) #ポートを選択

  Would you like to deploy a test environment? [? for help] (y/N) y # テスト環境としてデプロイするか選択

動かない..

アプリケーションのヘルスチェックで落ちて動かない。。

✔ Created ECR repositories for service greeting-app..

All right, you're all set for local development.
Deploy: Yes

✔ Linked account 680356542845 and region ap-northeast-1 to application greeting-app..

✔ Proposing infrastructure changes for the greeting-app-test environment.
- Creating the infrastructure for the greeting-app-test environment.     [create complete]  [92.1s]
  - An IAM Role for AWS CloudFormation to manage resources               [create complete]  [27.2s]
  - An ECS cluster to group your services                                [create complete]  [8.8s]
  - Enable long ARN formats for the authenticated AWS principal          [create complete]  [2.0s]
  - An IAM Role to describe resources in your environment                [create complete]  [23.8s]
  - A security group to allow your containers to talk to each other      [create complete]  [5.7s]
  - An Internet Gateway to connect to the public internet                [create complete]  [18.1s]
  - Private subnet 1 for resources with no internet access               [create complete]  [19.0s]
  - Private subnet 2 for resources with no internet access               [create complete]  [19.0s]
  - Public subnet 1 for resources that can access the internet           [create complete]  [19.0s]
  - Public subnet 2 for resources that can access the internet           [create complete]  [19.0s]
  - A Virtual Private Cloud to control networking of your AWS resources  [create complete]  [15.5s]
✔ Created environment test in region ap-northeast-1 under application greeting-app.
Environment test is already on the latest version v1.6.1, skip upgrade.
Building your container image: docker build -t 680356542845.dkr.ecr.ap-northeast-1.amazonaws.com/greeting-app/greeting-app --platform linux/amd64 /Users/masami/greeting -f /Users/masami/greeting/Dockerfile
[+] Building 2.2s (7/7) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                                                   0.0s
 => => transferring dockerfile: 36B                                                                                                                                                                    0.0s
 => [internal] load .dockerignore                                                                                                                                                                      0.0s
 => => transferring context: 2B                                                                                                                                                                        0.0s
 => [internal] load metadata for docker.io/library/openjdk:11-jdk-slim                                                                                                                                 2.1s
 => [internal] load build context                                                                                                                                                                      0.0s
 => => transferring context: 117B                                                                                                                                                                      0.0s
 => [1/2] FROM docker.io/library/openjdk:11-jdk-slim@sha256:ad41c90d47fdc84fecb3bdba2deb38e378bbde1d7f5a378ba0964c466b23dbca                                                                           0.0s
 => CACHED [2/2] COPY build/libs/greeting-0.0.1-SNAPSHOT.jar app.jar                                                                                                                                   0.0s
 => exporting to image                                                                                                                                                                                 0.0s
 => => exporting layers                                                                                                                                                                                0.0s
 => => writing image sha256:658315566f443e0dc2795c5d605d29ad71f4f9e512469135bc4c908425447ade                                                                                                           0.0s
 => => naming to 680356542845.dkr.ecr.ap-northeast-1.amazonaws.com/greeting-app/greeting-app                                                                                                           0.0s
Login Succeeded
Using default tag: latest
The push refers to repository [680356542845.dkr.ecr.ap-northeast-1.amazonaws.com/greeting-app/greeting-app]
408e323e553a: Pushed
007baf3afc22: Pushed
62763247decf: Pushed
2bf2b8c78141: Pushed
e8b689711f21: Pushed
latest: digest: sha256:09e11c29227fac3c7c730af1a9eb59fb7950d2003b2a984b6d7e790b452e8e94 size: 1372
✔ Proposing infrastructure changes for stack greeting-app-test-greeting-app
- Creating the infrastructure for stack greeting-app-test-greeting-app            [create complete]  [376.6s]
  - Service discovery for your services to communicate within the VPC             [create complete]  [0.0s]
  - Update your environment's shared resources                                    [update complete]  [181.1s]
    - A security group for your load balancer allowing HTTP and HTTPS traffic     [create complete]  [6.6s]
    - An Application Load Balancer to distribute public traffic to your services  [create complete]  [152.3s]
  - An IAM Role for the Fargate agent to make AWS API calls on your behalf        [create complete]  [27.6s]
  - A CloudWatch log group to hold your service logs                              [create complete]  [3.3s]
  - An ECS service to run and maintain your tasks in the environment cluster      [create complete]  [91.6s]
    Deployments
               Revision  Rollout        Desired  Running  Failed  Pending
      PRIMARY  2         [in progress]  1        1        1       0

    ✘ Latest failure event
      - (service greeting-app-test-greeting-app-Service-bfQWCpWYD0kA) (port 80
        ) is unhealthy in (target-group arn:aws:elasticloadbalancing:ap-northe
        ast-1:680356542845:targetgroup/greet-Targe-RCG2FPBWXXAQ/3d66f91ea0a3cf
        a1) due to (reason Health checks failed).
  - A target group to connect the load balancer to your service                   [create complete]  [4.0s]
  - An ECS task definition to group your containers and run them on ECS           [create complete]  [3.5s]
  - An IAM role to control permissions for the containers in your tasks           [create complete]  [23.6s]

調べたところM1 macだとデプロイで死ぬらしい(Dockerのアーキテクチャが異なるため). copilot init だと環境構築からアプリケーションのデプロイまで一括でやってくれるが、私の環境だとデプロイは別の方法で回避しないといけない。 以下コマンド等で個別にステップを実施できる。

$ copilot env init
$ copilot svc init
$ copilot svc deploy

# CodePipelineも作れる
$ copilot pipeline init
$ copilot pipeline update

アプリのデプロイはまたの機会に実施したい。

作成した環境のお片付け

# 作成したアプリケーションの確認
$ copilot app ls
greeting-app

# 削除
$ copilot app delete --name greeting-app
Sure? Yes

まとめ

起動まではいかなかったが、お手軽にWebサービスに必要な環境一式を揃えることができる便利ツールであることはわかった。
ネットワークの定義やIAM定義など、結構手間がかかることもやってくれるのは個人的にありがたい。 私が関わる案件では環境がterraformで整備されていることが多いのであまりお世話にならないが、個人でサクッとサービスを立ち上げるには打って付けだと思う。
一方で込み入った環境設定をしたい場合はCloudFormationの知識が必要となってくるので人によっては学習コストが発生する。
他にも細かい制約はありそうですが、今回はここまで。

【マッチングアプリをローンチするまで】#10

前回の更新からめちゃめちゃ期間があいてしまった。
うろ覚えだけどやったこと書いてきます。

3月後半~4月やったこと

3月3週 リファクタ、バグ修正 3月4週 dockerファイル作成
4月 swagger作成、API定義見直し ※別件で時間がほぼとれなかった。

5月からiphoneアプリ作れる人がjoinすることになったので、IF見直した。
また、別件が入り、4月はほとんど進捗がなかった。

swagger導入

spring/bootと同じ感覚でコメントにアノテーションを付けて作成したが、
springとは違いルーティング等を別ファイルで管理しているため効率的ではないことに気づいた。
現状はyamlファイルをこれ使って編集してる。
stoplight.io

GKE移行

GKE移行するためにdocker imageつくってます。色々覚えることが多くて大変だが、オンプレより断然良いね。
他にもやること山積みなので、優先度の高い仕事がない際に進めていきたい。

その他

せっかくVR用に高スぺPC買ったのにほぼ寝かせてる。。
有効活用したいい。。

【マッチングアプリをローンチするまで】#9

3月前半やったこと

3月1週 テーブル設計見直し、システム構成見直し、バグフィックス
3月2週 ユーザーの管理画面のモック作成

マッチング機能に加えて、イベントを主催する機能があるためイベント主催者のための管理画面を実装中。
業務の引継ぎと新しい現場スキルのキャッチアップのため、あまり時間とれなかった。

テーブル設計見直し

業務側のメンバーと交えてデータの持ち方を見直した。ある程度アプリのプロトタイプができており、初回の設計時から追加でほしい情報、削除する情報を整理できた。
また、データ解析のためどういうデータをログとして残したいかも議論した。
やはりプロトタイプがあるのと無いのとでは業務フローのイメージしやすさがすごく変わってくる。

システム構成変更

当初AWSでインフラ周りを構築する予定だったが、以下の理由により(ほぼ個人的な事情)GCP使うことにした。
- 私ともう一人の開発メンバーの次の現場がGCPを使用している。
- Kubernetes使ってみたい。→GKE良さそう
- 費用をざっくり見積もった結果GCPのが安そう
- ほぼAWSの機能使ってなかったので移行コストがかからない!!

時間あるときにシステム構成図上げます。。

現状の課題

リファクタリング・unitテスト

システム移行する前に、リファクタリングとunitテスト書いてテスト自動化しときたい。(サボってました。。)

その他

仕事忙しくて全然VRできてない(´;ω;`)
そうだ!!!VRの中でWEB開発すればよいのでは(闇深)

【Laravel】eloquent を使用していて、auto increment falseが効かなかった件

記事にするほどでもないが、メモがてら

事象

eloquentだとデフォルトでidがauto incrementですが、プレフィックスを付けたくてアプリ側でidを振る必要がでてきたのでauto incrementをfalseにしたが、反映されなかった。

環境

Laravel Framework 6.5.0

原因、対応

モデルの$fillableにidいれてなかったのでアプリ側で作ったIDがDBに反映されなかった。 $fillableにidを追加すると動作した。
エラーが返してくれれば良いのにauto incrementで入れてくれるんだね。

【マッチングアプリをローンチするまで】#8

2月後半やったこと

2月3週 クレジット決済機能追加
2月4週 クレジット決済機能追加 、リファクタリング

今回はプライベートが忙しくて、あまり進まなかった。

クレジット決済

stripeの実装完了、テスト用APIキーでの決済まで確認。
実装まで2週間ほどかかったが、実働は1日程度で作れた。
クレジット以外の決済方法にも対応させたいが、時間がとれないため初回はクレカ決済のみで。

現状の課題

リファクタリング

phpについてよく分かっていないので、javaっぽい感じでリファクタリングしている。
ネットで調べてみるとGoFデザインパターンphpデザインパターンを説明してるページがあるのでまあいいかと思っているが、 phpっぽい実装ができているか正直自信ない。

データのロードが遅い

インデックスを作ってない等、チューニングは一切していないが、それにしても遅い。
テーブル定義を見直す必要あり。

その他

Oculus Rift S とVR ReadyのPC購入。
念願のVR開発だ!!(時間ないけど...)

【Vue】filepond Postパラメータ渡し方

はじめに

filepondというライブラリを使用してファイルアップロード機能を実装していたが、postパラメータをサーバー側に渡すところで少し躓いたのでメモ。

環境

vue@2.6.11
vue-cli 2.9.6 Laravel Framework 6.5.0
filepond@4.9.5

やったこと

filepond インストール

filepondの導入と基本的な使い方はいろいろと記事があるので割愛。
参考にさせて頂いたサイト
pqina.nl

reffect.co.jp

File metadata プラグインインストール

公式ページのFile metadataの項目を参考にしてインストール

npm i filepond-plugin-file-metadata --save

vueファイル ユーザーIDをPostで送る

<template>
        <file-pond
          :server="url"
          allowRevert="false"
          instantUpload="false"
        />
</template>
<script>
import vueFilePond, { setOptions } from "vue-filepond";
import "filepond/dist/filepond.min.css";
/* Plugin */
import FilePondPluginFileMetadata from "filepond-plugin-file-metadata";
const FilePond = vueFilePond(
  FilePondPluginFileMetadata
);

export default {
  components: { FilePond },
  data() {
    return {
      url: "http://localhost:8000/api/fileupload",
      userId: 1,
    }
 },  
  /** 中略 */
  mounted() {
    //ここでパラメータをセット
    setOptions({
      fileMetadataObject: {
        userId: this.userId
      }
    });
  }
    ...

サーバー側(php)

use Illuminate\Http\Request;

    public function postFileUpload(Request $request)
    {
        $input = json_decode($request->input('filepond'));
        //ユーザーID取得
        $userId = $input->userId;

        //なんらかの処理
    }

終わりに

とりあえず動くが、ファイルのメタデータとしてデータを渡している?のは違和感がある。 良い方法があれば教えていただければうれすぃ

【マッチングアプリをローンチするまで】#7

2月前半やったこと

2月1週 既存不具合修正、お気に入りリスト的なやつ追加 2月2週 既存不具合修正、クレジット決済機能追加 2月3週 クレジット決済機能追加

クレジット決済

stripeを利用することで、簡単に実装することができそう。
手数料は3.6%掛かるが、クレジット番号等こちらで持たなくて良く、セキュリティ的な懸念が軽減された。
決済周り実装経験がなかったので苦戦すると思ったが、便利な世の中で助かった。
stripe.com

現状の課題

テーブル設計がいまいち感

初期のテーブル設計からカラムを拡張し、追加でテーブルを増やし、、ということが多々発生しているので、一度定義の見直しをした方が良いかもしれない。 あとログ全然吐いてないので、そのへんもそろそろ考えたい。

前回の課題全く対応できてない

ちょっと今月は時間なかった。。

その他

なんだかんだあってOculus Rift S 購入することに。
VR ready の PC買う。