Open12

友人とペアプロでWebアプリを作る過程の記録

ピン留めされたアイテム
ねおさんねおさん

概要

以下の目的があり、エンジニアの友人を誘ってペアプロでWebアプリを作ることにしました。

  • 業務外でなにかアプリを作りたい
  • システム構成やアーキテクチャ構築レベルから考えてアプリを作りたい
  • ペアプロによって生産性が上がるかを確かめたい
  • サーバレスなアプリを作りたい
  • 今ある知識でどの程度のアウトプットを作れるか確かめたい

作業過程を書き連ねていきます。

参加者一覧

HN(敬称略) 業界歴 技術スタック 備考
ねおさん 4年弱 業務ではAWS, Java, Vue, TypeScript / 業務外ではAtCoder Algo(茶), Rust 筆者
Teru 5年弱 Java, VB.NET / 業務外ではVue

作るもの

メンタリストDaigo氏の著書「コミュ障でも5分で増やせる超人脈術」で紹介されていた、
「ネットワークマップ」の作成と管理を容易にするアプリ

ユーザ自身の周辺人物情報を入力し、以下を表形式で出力できるもの

  • 自分にとっての重要人物(VIP)
  • そのVIPを紹介してくれた人物(Broker)
  • 自分がそのVIPを紹介した相手(Connect)
ねおさんねおさん

1回目

以下をざっくり4時間で行った。

  • 作成物の目的の説明
  • ペアプロのメリットなどを説明
    • レビューの手戻りをなくせる
    • 会話しながらの作業により、モチベーションを維持
    • お互いの知見・考えをその場で共有できる
    • 技量に差がある場合、互いにノウハウを得られる
  • ペアプロのルール決め
    • discordの画面共有で行う。
    • 25分ごとに5分休憩し、ドライバーとナビゲーターを交代
    • 4サイクルごとに20分休憩
  • 各種ツール決め
    • Notionでタスク管理
    • 必要なドキュメンテーションはGoogleスプレッドシート
  • システム構成作成
  • Notionアカウント作成
  • TerraformCloudアカウント作成

システム構成について

AWSベースで作成することにした。

想定しているシステム構成は以下の感じ

フロントエンド

  • AWS WAF
  • Route53
  • CloudFront
  • S3
    • Reactのアーティファクトを載せる

バックエンド

  • API Gateway
  • App Sync
  • Lambda
    • Rustで実装
  • Cognito
  • SES
    • 人脈見直しリマインダ機能を想定

DB

※暫定

  • Aurora Serverless ※v1かv2かは未定
  • TiDB Serverless

CI/CD

  • CodeCommit
  • CodeBuild
  • CodeDeploy
  • CodePipeline

運用保守系

  • CloudWatch
  • SystemManager
  • SecretsManager
ねおさんねおさん

ここまでで思ったこと

こうして書いてみると、
アーキテクチャレベルから考えたことがなく感覚でやっているので、
アーキテクチャ設計やモデリングなどは体系的に学習した方がいいかなと思った。

ねおさんねおさん

2回目までの下準備

制作用のAWSアカウントを作成
私個人のAWSからOrganizationsを有効化し、
作るアプリの開発と本番環境用のAWSアカウントと、
Identity Centerでそれらアカウントにログインできるユーザを作成
これに伴い、私個人用のIAMユーザを削除し、Identity Centerで作成したユーザを使用することにした。

ねおさんねおさん

第二回

以下をざっくり2時間で行った。

ローカル環境の有無について議論

動確のたびに開発環境を使用する場合、デプロイのロードタイムが長いため
結果、必要ということに

CodeCommitリポジトリ作成

以下四つのリポジトリをCodeCommitに作成

  • フロント用
  • バックエンド用
  • インフラ用
  • ローカル環境DB
    • DockerでローカルにPostgreSQLを構築する想定

aws-cliの設定, CodeCommitリポジトリのクローン

IdentityCenterを使用しているので、下記の手順を参考にクローン
https://dev.classmethod.jp/articles/iam-identiy-center-codecommit/

バックエンドのプロジェクトの初期化

serverless install --url https://github.com/softprops/serverless-aws-rust

フロントエンドのプロジェクト初期化

npx create-react-app  . --templete typescript
ねおさんねおさん

第三回

ざっくり1.5時間で以下を行った

dev環境作成準備

devを作ってからそれに合わせてローカルを作るべきと判断

dev環境作成にあたり、以下の流れをとる

  1. 試しにdev環境にterraformからs3バケットを作成する
  2. terraformとcodebuildでdev環境にリソースをつくるパイプラインをつくる
  3. devのリソース一式をつくる

1 試しにdev環境にterraformからs3バケットをつくる

dev環境のawsアカウントから仮のterraform用IAMユーザを作成

tfbuckendファイルを作成

backend/dev.tfbackend
bucket = ****
key    = "****dev.tfstate"
region = "ap-northeast-1"
profile = ****

tfvarsファイル作成

vars/dev.tfvars
project     = ****
environment = "dev"
domain      = ""

terraform init

terraform init -reconfigure -backend-config="backend/dev.tfbackend"
main.tf
# ------------------------
# - Variables
# ------------------------

variable "project" {
  type = string
}
variable "environment" {
  type = string
}
variable "domain" {
  type = string
}

# ------------------------
# - Terraform configuratoions
# ------------------------
terraform {
  required_version = ">1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~>3.0"
    }
  }
}

# ------------------------
# - Provider 
# ------------------------

provider "aws" {
  profile = ****
  region  = "ap-northeast-1"
} 
temps3bucket.tf
# -------------------
# S3 static bucket
# -------------------
resource "aws_s3_bucket" "s3_test_bucket" {
  bucket = "test-bucket-${var.project}-${var.environment}"
}

terraform apply

terraform apply --auto-approve -var-file vars/dev.tfvars 


tfstateがローカルに作成された

ねおさんねおさん

init時にwarnが出ていたのを見落としていた...

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Using previously-installed hashicorp/aws v3.76.1

╷
│ Warning: Missing backend configuration
│
│ -backend-config was used without a "backend" block in the configuration.
│
│ If you intended to override the default local backend configuration,
│ no action is required, but you may add an explicit backend block to your
│ configuration to clear this warning:
│
│ terraform {
│   backend "local" {}
│ }
│
│ However, if you intended to override a defined backend, please verify that
│ the backend configuration is present and valid.
│
╵
ねおさんねおさん

main.tfにbackendの設定を記載したら解決

main.tf
# ------------------------
# - Terraform configuratoions
# ------------------------
terraform {
  required_version = ">1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~>3.0"
    }
  }
+  backend "s3" {
+    bucket = ****
+    key    = "****dev.tfstate"
+    region = "ap-northeast-1"
+    profile = ****
+  }
}


必要な設定は.tfbackendに記載しているので空のブロックでもよかった。

main.tf
# ------------------------
# - Terraform configuratoions
# ------------------------
terraform {
  required_version = ">1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~>3.0"
    }
  }
+  backend "s3" {
+  }
}
ねおさんねおさん

DBに関する議論

Aurora Serverlessの問題点

データ層にAurora Serverlessを使うと考えていたが、以下の問題が発覚。

  • Aurora Serverless v2は非使用時にキャパシティ(ACU)を0にすることができない。最低0.5ACU
    • 東京リージョンで 1ACU/h あたり0.2 USD
    • 0.5ACUを一ヶ月換算で 0.1USD * 24h * 30d * 150 JPY/USD = 10800JPY / M
    • 個人開発で使うにはあまりにも高い
  • Aurora Serverless v1は2024年中にサービス終了する

代わりのDBを考える

代替案

  1. DynamoDB
  2. CockroachDB Serverless
  3. TiDB Serverless

DynamoDB

  • メリット
    • リソースをAWS内部で完結させることができる。
    • 従量課金制のため、個人開発の範疇では破茶滅茶な料金にはならないはず
  • デメリット
    • DynamoDB特有のデータ設計が必要

CockroachDB Serverless

https://www.cockroachlabs.com/pricing/

Free for use up to 10 GiB of storage and 50M RUs per organization per month.

  • メリット
    • NewSQL。Google Spannerのクローン
    • PostgreSQL互換のIF
    • 無料枠が大きい
    • SQLの知識を使用できる
  • デメリット
    • リソースをAWS内で完結できない
    • LambdaからCockroachDBを使用する際のコネクションなどの検証が必要

TiDB Serverless

https://pingcap.co.jp/tidb-cloud-serverless-pricing-details/

各組織で作成された5つのクラスタを無料で使用することができます。6つ目のクラスタを作成する場合は、クレジットカードを追加し、使用限度額を設定する必要があります。6つ目のクラスタを作成する前に、既に作成したクラスタをいくつか削除した場合、新しいクラスタは無料枠のクラスタとカウントされ無料となります。
上記の条件を満たしたTiDB Serverlessのクラスタに対して、毎月フリークォータが発行されます。無料枠を利用することで、お客様は1ヶ月間、行ベースのデータ5GiBと列ベースのデータ5GiBを同時に保存し、5,000万RUを消費することができます。これらのクォータを自由に割り当てて、同等の運用を実現することも可能です。

  • メリット
    • NewSQL
    • MySQL互換のIF
    • 無料枠が大きい
    • SQLの知識を使用できる
    • Cockroachと比較してQiitaなどに情報が多そう(雑感)
  • デメリット
    • リソースをAWS内で完結できない
    • LambdaからTiDBを使用する際のコネクションなどの検証が必要

結論

TiDB Serverlessを検証する方向性で一致

ねおさんねおさん

第四回

3時間で以下を行った。

dev環境Infraパイプライン作成

Codebuildプロジェクト作成

infraブランチのbuildspec.ymlを以下のように設定

buildspec.yml
version: 0.2

env:
  variables:
    TERRAFORM_VERSION: "1.7.5"

phases:
  install:
    commands:
      - curl -sL https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip > terraform.zip
      - unzip terraform.zip
      - mv terraform /usr/local/bin/
  pre_build:
    commands:
      - terraform init -backend-config="backend/${ENVIRONMENT}.tfbackend"
      - terraform validate
      - terraform plan -var-file vars/${ENVIRONMENT}.tfvars
  build:
    commands:
      - terraform apply --auto-approve -var-file vars/${ENVIRONMENT}.tfvars

{環境名}.tfvars{環境名}.tfbackendを使用するため、
環境変数で{環境名}を渡すように指定

また、Codebuildのサービスロールを使用するため、各.tfbackendからprofileの設定を削除した。

backend/dev.tfbackend
bucket = ****
key    = "****dev.tfstate"
region = "ap-northeast-1"
- profile = ****

以下は調査と試行錯誤しながら調整した。

  • pre_buildフェーズのterraformのインストール
  • CodeBuildのサービスロール
    • 初期設定の場合にinitが落ちることを確認し、backendのS3バケットへのアクセス許可を追加
    • backendのS3バケットへのアクセス許可だけ追加したとき、applyが失敗することを確認し、必要なサービスへのアクセスを許可

CodePipelineを作成

infraリポジトリのdevelopブランチの変更を検知し、
自動的にビルドプロジェクトを実行させるようにした。

次回の予定

AWSアカウントを分割しているPRD環境のInfraパイプラインを作成する。
PRD環境アカウントにCodeBuildプロジェクトとCodePipelineを作成し、
CodeBuildからDEV環境アカウントのCodeCommitリポジトリを参照させる設定を構築する。

↓の記事を参考にする予定。
https://dev.classmethod.jp/articles/codepipeline-cross-account/

ねおさんねおさん

第五回

1.5時間で以下を行った

Prd環境Infraパイプライン作成試行

下記記事を参考に一部変更して試行
https://dev.classmethod.jp/articles/codepipeline-cross-account/

ソースの受け渡しのためだけにS3バケットを使いたくないため、
Prd環境のCodeBuildプロジェクトをDev環境のCodeCommitをソースとするプロジェクトの作成を試行
また、CodeBuildが別アカウントのCodeCommitを見れるようにAssumeRoleの権限を付与

prd-codebuild.json
{
  "name": "****-infra-prd",
  "description": "cross account build project",
  "source": {
    "type": "CODECOMMIT",
    "location": "https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/****infra",
    "gitCloneDepth": 1,
    "gitSubmodulesConfig": {
      "fetchSubmodules": false
    },
    "buildspec": "",
    "insecureSsl": false
  },
  "sourceVersion": "refs/heads/master",
  "serviceRole": "arn:aws:iam::*****:role/******",
  "artifacts": {
    "type": "NO_ARTIFACTS"
  },
  "environment": {
    "type": "LINUX_CONTAINER",
    "image": "aws/codebuild/amazonlinux2-x86_64-standard:5.0",
    "computeType": "BUILD_GENERAL1_SMALL",
    "environmentVariables": [
      {
        "name": "ENVIRONMENT",
        "value": "prd",
        "type": "PLAINTEXT"
      }
    ],
    "privilegedMode": false,
    "imagePullCredentialsType": "CODEBUILD"
  }
}
aws codebuild create-project --cli-input-json file://prd-codebuild.json --profile {prd環境用profile}

リポジトリが存在するアカウントを指定できていないため(そもそもできるか要調査)
当然成功せず

リソース管理再構成案

以下の理由によりソースをGithubに移し、
パイプラインも含めてTerraformCloudで管理したほうがいいと考えた。

  • CodeBuild、ロール、ポリシー、CodePipelineを手動で作成してしまっており、管理が煩雑
  • Infra用のソースを含むリポジトリがDev環境のCodeCommitにある都合上、Infraのパイプラインがどうしても手動作成になる。

次回予定

ソースをすべてGithubに移し、Dev環境とPrd環境の各リソースをTerraformCloudで管理するように変更

ねおさんねおさん

第六回

2h近くで以下を実施

  • ソースをすべてGithubに移動
  • Dev環境とPrd環境のCodebuildプロジェクトおよびCodePipelineと、関連するIAMポリシー・ロールを削除

Githubの組織無料版の場合、ブランチ保護設定を付加することができないことが判明

次回予定

  • TerraformCloud連携
  • バックエンドパイプライン作成