どうも、DevOps チームの うすい です。
トトロも鬼滅の刃 無限列車編も見たことがありません。
今回新しいシステムを aws-sam-cli を用いて構築したので簡単にですがそれらの内容を記述したいと思います。AWS SAM 自体の説明は割愛します。
私のマシンの aws cli などのバージョンは下記となります。
$ aws --version aws-cli/1.16.79 Python/3.7.1 Darwin/19.6.0 botocore/1.12.69 $ sam --version SAM CLI, version 1.6.2
余談ですが aws-sam-cli のバージョンアップの速度はすごいですね。
AWS SAM では CloudFormation っぽいテンプレートファイルと samconfig.toml ファイルを使用します。samconfig.toml はsam deploy --guided
時に生成することもできますが今回は作成しておきます。
あまり情報は見かけませんが、samconfig.toml で ステージング環境 / 本番環境 といった環境に応じたパラメータが適用されるようにします。雰囲気は下記です。
version = 0.1 [default.build.parameters] profile = "dev" debug = true skip_pull_image = false use_container = true [default.deploy.parameters] stack_name = "hogehoge-dev" s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-dev" s3_prefix = "hogehoge" region = "ap-northeast-1" profile = "dev" confirm_changeset = false capabilities = "CAPABILITY_IAM" parameter_overrides = "Env=\"dev\"" [stg.build.parameters] profile = "stg" debug = true skip_pull_image = false use_container = true [stg.deploy.parameters] stack_name = "hogehoge-stg" s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-stg" s3_prefix = "hogehoge-stg" region = "ap-northeast-1" profile = "stg" confirm_changeset = true capabilities = "CAPABILITY_IAM" parameter_overrides = "Env=\"stg\"" [prd.build.parameters] profile = "prd" debug = false skip_pull_image = false use_container = true [prd.deploy.parameters] stack_name = "hogehoge-prd" s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-prd" s3_prefix = "hogehoge-prd" region = "ap-northeast-1" profile = "prd" confirm_changeset = true capabilities = "CAPABILITY_IAM" parameter_overrides = "Env=\"prd\""
一番最後の[prd.deploy.parameters]
を例にして説明すると、この部分は[環境.コマンド.aws-sam-cliに渡すパラメータ]
となります。このセクションで各パラメータを設定しておくことで、コマンド実行が楽になります(後述)。また、profile
は AWS CLI の config と同じものを記載してください。parameter_overrides
で環境名でEnv
パラメータを上書き指定しています。
それでは API Gateway と Lambda Authorizer と DynamoDB を用いた雰囲気tempalte.yaml
をご覧ください。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > hoge serverless service Globals: Function: Timeout: 3 Runtime: python3.8 Environment: Variables: ENV: !Ref Env HOGE_API_HOST: !Ref HogeApiHost Layers: - !Ref MyLayer VpcConfig: SecurityGroupIds: !FindInMap [ SecurityGroup, !Ref Env, SecurityGroupIds ] SubnetIds: !FindInMap [ SubnetId, !Ref Env, SubnetIds ] Parameters: Env: Type: String AllowedValues: - prd - stg - dev Default: dev HogeApiHost: Type: AWS::SSM::Parameter::Value<String> Default: /hoge/api/host Conditions: IsDev: !Equals [ !Ref Env, dev ] Mappings: SecurityGroup: prd: SecurityGroupIds: - sg-hoge-prd stg: SecurityGroupIds: - sg-hoge-stg dev: SecurityGroupIds: - sg-hoge-dev SubnetId: prd: SubnetIds: - hoge-prd1 - hoge-prd2 stg: SubnetIds: - hoge-stg1 - hoge-stg2 dev: SubnetIds: - hoge-dev1 - hoge-dev2 Resources: MyApi: Type: AWS::Serverless::Api Properties: StageName: !Ref Env Auth: DefaultAuthorizer: TokenAuth AddDefaultAuthorizerToCorsPreflight: False Authorizers: TokenAuth: FunctionPayloadType: TOKEN FunctionArn: !GetAtt authorizerFunction.Arn Identity: Header: Authorization ReauthorizeEvery: 0 authorizerFunction: Type: AWS::Serverless::Function Properties: CodeUri: functions/authorizer/ Handler: app.lambda_handler Description: API Gateway Lambda Authorizer Policies: - DynamoDBCrudPolicy: TableName: !Ref Hogetable - AmazonSSMReadOnlyAccess # Lambda Layer MyLayer: Type: AWS::Serverless::LayerVersion Properties: LayerName: hogehoge-service Description: "" ContentUri: service/ CompatibleRuntimes: - python3.8 Metadata: BuildMethod: python3.8 # DynamoDB HogeTable: Type: AWS::DynamoDB::Table Properties: TableName: Hogetable AttributeDefinitions: - AttributeName: id AttributeType: N KeySchema: - AttributeName: id KeyType: HASH ProvisionedThroughput: !If [IsDev, { "ReadCapacityUnits": 5, "WriteCapacityUnits": 5 }, !Ref AWS::NoValue] BillingMode: !If [IsDev, !Ref AWS::NoValue, PAY_PER_REQUEST] Outputs: WebEndpoint: Description: "API Gateway endpoint URL" Value: !Sub "https://${MyApi}.execute-api.${AWS::Region}.amazonaws.com/${Env}/"
ほとんど CloudFormation のテンプレートですね。Globals:
とか sam 特有に見えますが CloudFormation でも使えるみたいです(未確認)。
雰囲気だけではなんなので、テクニック的なことも書きますと
Parameters:
のところでType: AWS::SSM::Parameter::Value<String>
を使用し Parameter Store の値を取得Conditions:
でEnv
がdev
でないときに DynamoDB のテーブルを Provisioned ではなく OnDemand で作成
といったことをしています。
実際にステージング環境にデプロイするにはまず
$ sam build --config-env stg
とビルドします。samconfig.toml に色々と設定しているのでコマンド自体はシンプルですね。最終的に下記のような出力を確認できます。
Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Invoke Function: sam local invoke [*] Deploy: sam deploy --guided
Artifacts が出力されているディレクトリの中には CloudFormation のテンプレートも出力されます。
それではデプロイしてみましょう。出力内容は雰囲気です。toml ファイルでconfirm_changeset = true
としていますので、ChangeSet の確認が途中で入ります。
$ sam deploy --config-env stg Uploading to hogehoge-stg/xxxxxxxxxxxxxxxxxxxxxxx 5000 / 5000.0 (100.00%) Deploying with following values =============================== Stack name : hogehoge-stg Region : ap-northeast-1 Confirm changeset : True Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-stg Capabilities : ["CAPABILITY_IAM"] Parameter overrides : {'Env': 'stg'} CloudFormation stack changeset --------------------------------------------------------------------------------------------------------------------------------------------------------- Operation LogicalResourceId ResourceType Replacement --------------------------------------------------------------------------------------------------------------------------------------------------------- + Add MyApiDeploymentxxxxxxxxxx AWS::ApiGateway::Deployment N/A + Add MyApiStage AWS::ApiGateway::Stage N/A --------------------------------------------------------------------------------------------------------------------------------------------------------- Changeset created successfully. arn:aws:cloudformation:hoge Previewing CloudFormation changeset before deployment ====================================================== Deploy this changeset? [y/N]: y <--------------- y を入力すると反映されます CloudFormation events from changeset --------------------------------------------------------------------------------------------------------------------------------------------------------- ResourceStatus ResourceType LogicalResourceId ResourceStatusReason --------------------------------------------------------------------------------------------------------------------------------------------------------- CREATE_IN_PROGRESS AWS::ApiGateway::RestApi MyApi - CREATE_IN_PROGRESS AWS::ApiGateway::RestApi MyApi Resource creation Initiated CREATE_COMPLETE AWS::ApiGateway::RestApi MyApi - 〜〜 省略 〜〜 --------------------------------------------------------------------------------------------------------------------------------------------------------- CloudFormation outputs from deployed stack ----------------------------------------------------------------------------------------------------------------------------------------------------------- Outputs ----------------------------------------------------------------------------------------------------------------------------------------------------------- Key WebEndpoint Description API Gateway endpoint URL Value https://hogehogehoge.execute-api.ap-northeast-1.amazonaws.com/stg/ -----------------------------------------------------------------------------------------------------------------------------------------------------------
と分かりにくいですがResourceStatus
の値が変化しながら処理が進み、最後に template.yaml のOutputs
で指定した値が出力されます。
一番右のReplacement
の値に注意しながら運用していこうと思います。