継続的インテグレーション環境の構築(3)

【連載】

AWSで実践! 基盤構築・デプロイ自動化

【第42回】継続的インテグレーション環境の構築(3)

[2020/10/14 09:00]川畑 光平 ブックマーク ブックマーク

本連載では、AWSリソース基盤構築の自動化を実践しています。現在は、第2回から解説してきた継続的インテグレーション環境をCloudFormationを使って自動構築する方法について解説しています。

構成図

前回は、CloudFormationのカスタムリソースを使ってRDS構築後のデータベースにユーザーを追加する処理をLambdaファンクションとして実装し、S3バケットへアップロードしました。続く今回は、LambdaをデプロイするCloudFormationや前回実装したファンクションを実行するカスタムリソーステンプレートを作成します。

なお、実際のソースコードはGitHub上にコミットしています。以降のソースコードでは本質的でない記述を一部省略しているので、実行コードを作成する場合は、必要に応じて適宜GitHub上のソースコードも参照してください。

Lambdaをデプロイするテンプレート

それではまず、LambdaファクションをデプロイするCloudFormationテンプレートを実装します。

AWSTemplateFormatVersion: '2010-09-09'

Description: Lambda for create user in RDS template with YAML - Depends On base/1-vpc-cfn.yml, base/2-sg-cfn.yml.

// omit

Resources:
  LambdaForCreatingTableInRds:
    Type: AWS::Lambda::Function                                              # (A)
    Properties:
      Code:
        S3Bucket:
          Fn::ImportValue: !Sub ${VPCName}-Lambda-S3Bucket                   # (B)
      S3Key: mynavi-sample-sonarqube-initdb-0.0.1-SNAPSHOT-aws.jar           # (C)
      Handler: org.debugroom.mynavi.sample.sonarqube.initdb.app.handler.LambdaTriggerHandler::handleRequest
                                                                             # (D)
      FunctionName: mynavi-sonarqube-cfn-rds-dbinit-function
      Environment:
        Variables:
          FUNCTION_NAME: initDBFunction                                      # (E)
      MemorySize: 1024                                                       # (F)
      Runtime: java8
      Timeout: 120
      VpcConfig:                                                             # (G)
        SecurityGroupIds:
          - Fn::ImportValue: !Sub ${VPCName}-SecurityGroupLambda             # (H)
        SubnetIds:                                                           # (I)
          - Fn::ImportValue: !Sub ${VPCName}-PrivateSubnet1
          - Fn::ImportValue: !Sub ${VPCName}-PrivateSubnet2
      Role: !GetAtt LambdaRDSAccessRole.Arn                                  # (J)

  LambdaRDSAccessRole:                                                       # (K)
    Type: AWS::IAM::Role
    Properties:
      Path: /
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
        ManagedPolicyArns:
          - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
                                                                             # (L)

  CloudFormationAccessPolicy:                                                # (M)
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: ma-Lambda-CloudFormationAccessPolicy
      PolicyDocument:
        Statement:
          - Effect: Allow
            Action:
              - "cloudformation:*"
            Resource: "*"
      Roles:
        - !Ref LambdaRDSAccessRole

  SSMAccessPolicy:                                                           # (N)
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: ma-lambda-SSMAccessPolicy
      PolicyDocument:
        Statement:
          - Effect: Allow
            Action:
            - "cloudwatch:PutMetricData"
            # omit
      Roles:
        - !Ref LambdaRDSAccessRole

Outputs:                                                                     # (O)
  LambdaForCreateUserInRdsArn:
    Description: Lambda function for creating table in rds
    Value: !GetAtt LambdaForCreatingTableInRds.Arn
    Export:
      Name: !Sub ${VPCName}-LamdaForCreateUserInRdsArn

テンプレートのポイントになる箇所は以下の通りです。

項番 説明
A Lambdaファンクションとしてのリソースを定義します。定義の詳細は「AWS::Lambda::Function 」も参照してください
B 前々回作成したデプロイ用S3テンプレートのOutput要素で出力したバケット名をクロススタックリファレンスを使って取得します
C 前回作成したシェルスクリプト内でMavenビルド/S3へアップロードしたLambdaファンクションのJarファイル名を指定します
D 前回実装したHandlerクラスのFQCNとハンドラメソッドを指定します
E 連載「AWSで作るクラウドネイティブアプリケーションの基本」の第2回 と同様、環境変数にFUNCTION_NAMEとして、ファンクションクラスとなるBean名を指定しておきます(Spring Cloud Functionでは、実行する関数を環境変数FUNCTION_NAMEで指定したBean名で取得するためです)
F ファンクション実行時のメモリサイズを指定します。SpringアプリケーションをLambdaで実行する場合1024MB以上のメモリサイズを確保しなければ、起動時間が大幅にかかってしまうケースがあります
G Lambdaが接続するVPCの設定を行います
H Lambdaに割り当てるセキュリティグループを指定します。前々回セキュリティグループのテンプレートで実装した通り、このセキュリティグループはRDSの接続が許可されています
I Lambdaに割り当てるサブネットを指定します。ここではプライベートサブネットを指定しておきます
J Lambdaに設定するIAMロールのARNを指定します。ここではKで定義したARNを設定します
K Lambdaに設定するIAMロールを定義します。ファンクション内の実装では、CloudFormationのスタック参照、SystemsManager Parameter Storeの参照を行いますが、M、Nで定義したポリシーからアタッチして、このロールを参照するように設定します
L LambdaがVPCにアクセスするために必要な、AWSLambdaVPCAccessExecutionRoleをアタッチします。詳細はAWS Lambdaの開発者ガイドの「VPC内のリソースにアクセスするためのLambda関数の設定」も参照してください
M CloudFormationスタックのアクセスを可能にするIAMポリシーを定義し、Kのロールへアタッチします
N SystemsManager Parameter Storeへのアクセスを可能にするIAMポリシーを定義し、Kのロールへアタッチします
O 後述するカスタムリソーステンプレートのイベント設定で参照するため、LambdaファンクションのARNをOutput要素として出力します

作成したテンプレートをCLIなどで実行し、Lambdaファンクションをデプロイします。

Lambdaを起動するカスタムリソーステンプレート

次に、このLambdaを起動するカスタムリソーステンプレートを作成します。ServiceTokenには、上述のコードの0で出力したLambdaファンクションのARNを指定します。

# omit

Resources:
  LambdaTrigger:
    Type: Custom::LambdaTrigger
    Properties:
      ServiceToken:
        Fn::ImportValue: !Sub ${VPCName}-LamdaForCreateUserInRdsArn
       Region: !Ref "AWS::Region"

このテンプレートを実行すると、Lambdaが起動して、CloudWatch LogsにデプロイしたLambdaファンクションの実行ログが出力されます。

Lambdaファンクションの実行ログ

もし実行時にエラーが発生し、Lambdaファンクション内でResponseURLにシグナルを送れずに終わってしまうと、CloudFormationのスタックのステータスがProgress中で止まったままとなります。その場合は、AWSナレッジセンターのサポートページを参考にCloudWatch Logsに出力された ResponseURL、StackId、RequestIdなどのパラメータを指定し、直接リクエストを送信してステータスを完了させるほうが簡単です(そのままにしておいても1時間後にエラーになって終わるだけです)。

* * *

今回はLambdaをデプロイするCloudFormationと、前回実装したファンクションを実行するカスタムリソーステンプレートを作成し、RDSへの初期化処理を行うLambdaファンクションを実行しました。次回は、SonarQubeServerを起動するCloudFormationテンプレートを実装します。

著者紹介


川畑 光平(KAWABATA Kohei) - NTTデータ

金融機関システム業務アプリケーション開発・システム基盤担当、ソフトウェア開発自動化関連の研究開発を経て、デジタル技術関連の研究開発・推進に従事。

Red Hat Certified Engineer、Pivotal Certified Spring Professional、AWS Certified Solutions Architect Professional等の資格を持ち、アプリケーション基盤・クラウドなど様々な開発プロジェクト支援にも携わる。AWS Top Engineers & Ambassadors選出。

本連載の内容に対するご意見・ご質問は Facebook まで。

※ 本記事は掲載時点の情報であり、最新のものとは異なる場合がございます。予めご了承ください。

一覧はこちら

連載目次

もっと知りたい!こちらもオススメ

【連載】Kubernetes入門 [15] CI/CDにおける潮流 - CIOpsからGitOpsへ

【連載】Kubernetes入門 [15] CI/CDにおける潮流 - CIOpsからGitOpsへ

今回は、CI/CDツールについてGitOpsやIaC(Infrastructure as Code)など、さまざまな側面から紹介することで、位置付けをより深く理解していただきます。なお、個別のCI/CD系のツールの使い方などの詳細については次回以降紹介します。

関連リンク

この記事に興味を持ったら"いいね!"を Click
Facebook で IT Search+ の人気記事をお届けします
注目の特集/連載
[解説動画] Googleアナリティクス分析&活用講座 - Webサイト改善の正しい考え方
[解説動画] 個人の業務効率化術 - 短時間集中はこうして作る
ミッションステートメント
教えてカナコさん! これならわかるAI入門
AWSではじめる機械学習 ~サービスを知り、実装を学ぶ~
対話システムをつくろう! Python超入門
Kubernetes入門
SAFeでつくる「DXに強い組織」~企業の課題を解決する13のアプローチ~
PowerShell Core入門
AWSで作るマイクロサービス
マイナビニュース スペシャルセミナー 講演レポート/当日講演資料 まとめ
セキュリティアワード特設ページ

一覧はこちら

今注目のIT用語の意味を事典でチェック!

一覧はこちら

会員登録(無料)

ページの先頭に戻る