0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWSで筋トレ進捗記録3(構成のIaC化)

0
Posted at

この記事は何

前回までコンソールでポチポチ作っていた運動記録の構成を、AWS SAMでコード化(IaC化)し、sam deploy一発で立ち上がるところまで持っていった記録です。2分で読めます。

image.png
完成した構成のアーキテクチャ図

背景

これまで運動記録AppSheet + 手動で管理していましたが、「同じ構成を誰でも再現できる形にしたい」「インフラをコードで管理する感覚を身につけたい」と思い、SAMでIaC化に挑戦しました。

構成

  • AWS Lambda:筋トレのボリュームを計算
  • Amazon DynamoDB:運動記録を保存
  • AWS SES:土曜日21時に今週の筋トレの総ボリューム数と有酸素運動の合計時間と走行距離をメール通知

IAMポリシーを自分でJSONで書かずに済むのがSAMの利点でした。
以下はtemplate.yamlのAWS Lambda、DynamoDB、Lambda+SESの部分です。

# ── 記録用 Lambda(筋トレ)───────────────────────
  WorkoutFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: workout_lambda_SAM_Test
      CodeUri: functions/workout/
      Handler: lambda_function.lambda_handler
      Environment:
        Variables:
          TABLE_NAME: WorkoutRecords_SAM_Test
      Policies:
        - DynamoDBCrudPolicy:
            TableName: WorkoutRecords_SAM_Test
      Events:
        Api:
          Type: HttpApi
          Properties:
            ApiId: !Ref WorkoutExerciseApi
            Path: /workout
            Method: ANY

  # ── 記録用 Lambda(有酸素)───────────────────────
  ExerciseFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: exercise_lambda_SAM_Test
      CodeUri: functions/exercise/
      Handler: lambda_function.lambda_handler
      Environment:
        Variables:
          TABLE_NAME: ExerciseRecords_SAM_Test
      Policies:
        - DynamoDBCrudPolicy:
            TableName: ExerciseRecords_SAM_Test
      Events:
        Api:
          Type: HttpApi
          Properties:
            ApiId: !Ref WorkoutExerciseApi
            Path: /exercise
            Method: ANY
  # ── DynamoDB テーブル ─────────────────────────────
  WorkoutTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: WorkoutRecords_SAM_Test
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: user_id
          AttributeType: S
        - AttributeName: record_id
          AttributeType: S
        - AttributeName: body_part
          AttributeType: S
        - AttributeName: date
          AttributeType: S
      KeySchema:
        - AttributeName: user_id
          KeyType: HASH
        - AttributeName: record_id
          KeyType: RANGE
      GlobalSecondaryIndexes:
        - IndexName: body_part-date-index
          KeySchema:
            - AttributeName: body_part
              KeyType: HASH
            - AttributeName: date
              KeyType: RANGE
          Projection:
            ProjectionType: ALL
      StreamSpecification:
        StreamViewType: NEW_IMAGE

  ExerciseTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: ExerciseRecords_SAM_Test
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: user_id
          AttributeType: S
        - AttributeName: record_id
          AttributeType: S
      KeySchema:
        - AttributeName: user_id
          KeyType: HASH
        - AttributeName: record_id
          KeyType: RANGE
      StreamSpecification:
        StreamViewType: NEW_IMAGE
 # ── 週次レポート Lambda(筋トレ)─────────────────
  WorkoutWeeklyReportFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: workout_weekly_report_SAM_Test
      CodeUri: functions/workout_weekly_report/
      Handler: lambda_function.lambda_handler
      Environment:
        Variables:
          TABLE_NAME: WorkoutRecords_SAM_Test
          SES_SENDER: !Ref SesSender
          SES_RECIPIENT: !Ref SesRecipient
      Policies:
        - DynamoDBReadPolicy:
            TableName: WorkoutRecords_SAM_Test
        - Statement:
            - Effect: Allow
              Action:
                - ses:SendEmail
                - ses:SendRawEmail
              Resource: '*'
      Events:
        WeeklySchedule:
          Type: ScheduleV2
          Properties:
            ScheduleExpression: cron(0 21 ? * SAT *)
            ScheduleExpressionTimezone: Asia/Tokyo

  # ── 週次レポート Lambda(有酸素)─────────────────
  ExerciseWeeklyReportFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: exercise_weekly_report_SAM_Test
      CodeUri: functions/exercise_weekly_report/
      Handler: lambda_function.lambda_handler
      Environment:
        Variables:
          TABLE_NAME: ExerciseRecords_SAM_Test
          SES_SENDER: !Ref SesSender
          SES_RECIPIENT: !Ref SesRecipient
      Policies:
        - DynamoDBReadPolicy:
            TableName: ExerciseRecords_SAM_Test
        - Statement:
            - Effect: Allow
              Action:
                - ses:SendEmail
                - ses:SendRawEmail
              Resource: '*'
      Events:
        WeeklySchedule:
          Type: ScheduleV2
          Properties:
            ScheduleExpression: cron(0 21 ? * SAT *)
            ScheduleExpressionTimezone: Asia/Tokyo

やったこと

  1. sam init で雛形を作成
  2. template.yaml にLambda + DynamoDBを定義
  3. sam buildsam deploy
  4. Lambdaを叩いてDynamoDBに記録が入ることを確認

image.png

動作結果

sam remote invoke でLambdaを叩き、DynamoDBにレコードが1件書き込まれることを確認)。

image.png
ターミナル

image.png
DymamoDBのテーブルに書き込まれていることを確認

つまずいた点

  • Python 3.14を指定していたが手元は3.13だったため、ビルドが失敗した。テンプレートのPythonバージョンを変えて解決した。

今後やりたいこと

  • DynamoDB Streams の追加(運動当日の夜に頑張ったねメールがあると嬉しいから)

まとめ・所感

コンソールで作った構成を、コードから再現可能な形にできました。sam deletesam deploy で消して戻せることも確認済みです。

最初はSAMの構文意味がわからなかったけど、公式ドキュメントを参照しながら読むと段々と内容を理解できてきてある程度読めるようになった。今後は公式ドキュメントをベースに内容の理解に努めていきたい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?