次は aws 側(クラウド側)にデプロイしてみます。
- WSL 上に Lambda のローカル実行環境を作る:実行環境を作る (1/3)
- WSL 上に Lambda のローカル実行環境を作る:ローカルでデバッグ (2/3)
- WSL 上に Lambda のローカル実行環境を作る:aws にデプロイ (3/3) <- いまここ
デプロイ
当初から参考にしていたこちらのシリーズの記事
サーバーレスのローカル開発環境を整備する ~後編 - 変化を求めるデベロッパーを応援するウェブマガジン | AWS
では、デプロイにも触れてますが、かなりざっくりとしています。
実際の選択肢などは、こちらのチュートリアルのほうが詳しいです。
チュートリアル: で Hello World アプリケーションをデプロイする AWS SAM - AWS Serverless Application Model
ということで、この部分はこのチュートリアルに従ってやってみたいと思います。
早速やってみます。
複数のプロファイルがあるので、デプロイコマンドを呼び出す際に、プロファイル名を引数で与えます。
(.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ sam deploy --guided --profile sample_prof Configuring SAM deploy ====================== Looking for config file [samconfig.toml] : Found Reading default arguments : Success Setting default arguments for 'sam deploy' ========================================= Stack Name [sam-hello-world]: AWS Region [us-east-1]: ap-northeast-1 #Shows you resources changes to be deployed and require a 'Y' to initiate deploy Confirm changes before deploy [Y/n]: n #SAM needs permission to be able to create roles to connect to the resources in your template Allow SAM CLI IAM role creation [Y/n]: #Preserves the state of previously provisioned resources when an operation fails Disable rollback [y/N]: HelloWorldFunction has no authentication. Is this okay? [y/N]: y Save arguments to configuration file [Y/n]: SAM configuration file [samconfig.toml]: SAM configuration environment [default]:
各オプションは、チュートリアルに従いました。ここまで入力すると、デプロイが始まります。
ですが、なんと、エラーになりました。
Error: Failed to create/update the stack: sam-hello-world, Waiter StackCreateComplete failed: Waiter encountered a terminal failure state: For expression "Stacks[].StackStatus" we matched expected path: "ROLLBACK_FAILED" at least once
詳細が出ているので、追いかけると
Resource handler returned message: "Encountered a permissions error performing a tagging operation, please add required tag permissions. See https://repost.aws/knowledge- center/cloudformation-tagging-permission- error for how to resolve. Resource handler returned message: "User: arn:aws:iam::xxxxxxxxxxxx:user/sample_prof is not authorized to perform: iam:CreateRole on resource: arn:aws:iam::xxxxxxxxxxxx:role/sam-hello- world-HelloWorldFunctionRole-xxxxxxxxxxxx because no identity-based policy allows the iam:CreateRole action (Service: Iam, Status Code: 403, Request ID: xxxxxxxxxxxxxxxx)"" RequestToken: xxxxxxxxxxxxxxxx, HandlerErrorCode: UnauthorizedTaggingOperation)
iam の CreateRole の権限がないためのエラーのようです。
IAM ユーザーの権限を追加
権限でエラーが起きているとなると、表示された権限以外にも必要な権限がありそうです。ということで、ネットを調べてみると、下記の記事に必要な権限一覧がありました。
AWS Lambdaのデプロイに必要なIAMポリシーについて #lambda - Qiita
今、試しているアカウントは、テスト用ということで、 PowerUserAccess の権限を与えています。この権限だと、IAM 関連の権限に制限が入っているので、これだけ、追加で許可してやることにします。
ということで、下記のようなポリシーを作成して、このアカウントにアタッチしておきます。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "iam:GetRole", "iam:PassRole", "iam:DetachRolePolicy", "iam:TagRole", "iam:CreateRole", "iam:DeleteRole", "iam:AttachRolePolicy", "iam:UpdateRole", "iam:PutRolePolicy", "iam:CreateUser" ], "Resource": "*" } ] }
上記の記事の権限に加えて、 iam:TagRole を追加しています(何度か試した結果、これも必要だと怒られたためです)。
デプロイ失敗時のリソースを削除
再度デプロイを試す前に、作成途中のリソースを一度、削除しておきます。
(.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ sam delete --profile sample_prof Are you sure you want to delete the stack sam-hello-world in the region ap-northeast-1 ? [y/N]: y Are you sure you want to delete the folder sam-hello-world in S3 which contains the artifacts? [y/N]: y - Deleting S3 object with key sam-hello-world/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - Deleting S3 object with key sam-hello-world/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.template - Deleting Cloudformation stack sam-hello-world Deleted successfully (.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$
で、これで全部消えたかと思って、念のために aws のコンソールから見てみると、 CloudFormation にスタックが残ってます。
どうも、これは SAM で共通に使う S3 バケットのようです。
もう一度、最初から作るのを確認したいので、これも削除しておきます。
なお、 CloudFormation でスタックの削除を行っても、エラーで消えない場合があります。これは、 S3 のバケット内にオブジェクトが残っていると消えないためです。しかし、バケットを見てもオブジェクトがありません。
が、これはバージョニングが有効になっている場合に、古いオブジェクトがあるとエラーになるという罠になってます。実際、『バージョンの表示』をクリックすると消えたはずのオブジェクトが再度表示されます。
ということで、
AWS S3 クイズ ~バケットが空ではない?~ #AWS - Qiita
の記事などを参考にして、バケットからオブジェクトをすべて削除しておいてから、 CloudFormation のスタックを削除します。または、一度 CloudFormation で削除に失敗すると、同じスタックの再削除の際に以前失敗したリソースの削除をスキップするか尋ねられるので、そちらではスキップを選択してスタックを削除後、手作業で S3 バケットを消すという方法もあります。
いずれにしても無事に消えたのを確認しておきます。
再デプロイ
一度、きれいにしたら、再度デプロイです。
(.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ sam deploy --guided --profile sample_prof Configuring SAM deploy ====================== Looking for config file [samconfig.toml] : Found Reading default arguments : Success Setting default arguments for 'sam deploy' ========================================= Stack Name [sam-hello-world]: AWS Region [ap-northeast-1]: #Shows you resources changes to be deployed and require a 'Y' to initiate deploy Confirm changes before deploy [Y/n]: n #SAM needs permission to be able to create roles to connect to the resources in your template Allow SAM CLI IAM role creation [Y/n]: #Preserves the state of previously provisioned resources when an operation fails Disable rollback [y/N]: HelloWorldFunction has no authentication. Is this okay? [y/N]: y Save arguments to configuration file [Y/n]: SAM configuration file [samconfig.toml]: SAM configuration environment [default]: Looking for resources needed for deployment: Creating the required resources... Successfully created! Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxxx A different default S3 bucket can be set in samconfig.toml and auto resolution of buckets turned off by setting resolve_s3=False Parameter "stack_name=sam-hello-world" in [default.deploy.parameters] is defined as a global parameter [default.global.parameters]. This parameter will be only saved under [default.global.parameters] in /home/mor/tmp/sam_samples/sam-hello-world/samconfig.toml. Saved arguments to config file Running 'sam deploy' for future deployments will use the parameters saved above. The above parameters can be changed by modifying samconfig.toml Learn more about samconfig.toml syntax at https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html Uploading to sam-hello-world/ea54f8c447ec2d2acbd568a24d797ab4 573488 / 573488 (100.00%) Deploying with following values =============================== Stack name : sam-hello-world Region : ap-northeast-1 Confirm changeset : False Disable rollback : False Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxxx Capabilities : ["CAPABILITY_IAM"] Parameter overrides : {} Signing Profiles : {} Initiating deployment ===================== Uploading to sam-hello-world/89c7047fabf664fbcdcbd705c01e8d9d.template 1204 / 1204 (100.00%) Waiting for changeset to be created.. CloudFormation stack changeset --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Operation LogicalResourceId ResourceType Replacement --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Add HelloWorldFunctionHelloWorldPermissionProd AWS::Lambda::Permission N/A + Add HelloWorldFunctionRole AWS::IAM::Role N/A + Add HelloWorldFunction AWS::Lambda::Function N/A + Add ServerlessRestApiDeploymentxxxxxxxxxx AWS::ApiGateway::Deployment N/A + Add ServerlessRestApiProdStage AWS::ApiGateway::Stage N/A + Add ServerlessRestApi AWS::ApiGateway::RestApi N/A --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxx:changeSet/samcli-deploy1733987739/541c8bc1-81e7-436f-b68c-7326d868a648 2024-12-12 16:15:45 - Waiting for stack create/update to complete CloudFormation events from stack operations (refresh every 5.0 seconds) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ResourceStatus ResourceType LogicalResourceId ResourceStatusReason --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- CREATE_IN_PROGRESS AWS::CloudFormation::Stack sam-hello-world User Initiated CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole - CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole Resource creation Initiated CREATE_COMPLETE AWS::IAM::Role HelloWorldFunctionRole - CREATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction - CREATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction Resource creation Initiated CREATE_IN_PROGRESS - CONFIGURATION_COMPLETE AWS::Lambda::Function HelloWorldFunction Eventual consistency check initiated CREATE_IN_PROGRESS AWS::ApiGateway::RestApi ServerlessRestApi - CREATE_IN_PROGRESS AWS::ApiGateway::RestApi ServerlessRestApi Resource creation Initiated CREATE_COMPLETE AWS::ApiGateway::RestApi ServerlessRestApi - CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeploymentxxxxxxxxxx - CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermissionProd - CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermissionProd Resource creation Initiated CREATE_COMPLETE AWS::Lambda::Function HelloWorldFunction - CREATE_COMPLETE AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermissionProd - CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeploymentxxxxxxxxxx Resource creation Initiated CREATE_COMPLETE AWS::ApiGateway::Deployment ServerlessRestApiDeploymentxxxxxxxxxx - CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdStage - CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdStage Resource creation Initiated CREATE_COMPLETE AWS::ApiGateway::Stage ServerlessRestApiProdStage - CREATE_COMPLETE AWS::CloudFormation::Stack sam-hello-world - --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- CloudFormation outputs from deployed stack ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Outputs ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Key HelloWorldFunctionIamRole Description Implicit IAM Role created for Hello World function Value arn:aws:iam::xxxxxxxxxx:role/sam-hello-world-HelloWorldFunctionRole-xxxxxxxxxx Key HelloWorldApi Description API Gateway endpoint URL for Prod stage for Hello World function Value https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ Key HelloWorldFunction Description Hello World Lambda Function ARN Value arn:aws:lambda:ap-northeast-1:xxxxxxxxxx:function:sam-hello-world-HelloWorldFunction-xxxxxxxxxx ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Successfully created/updated stack - sam-hello-world in ap-northeast-1 (.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$
やっとうまくいきましたね。
作成されたリソースの確認
一応、作成されたものを確認しておきます。CLoudFormation をみると、スタックが2つ作られています。
sam-hello-world という名前のスタックが今回のアプリケーション固有のスタックです。
一方、 aws-sam-cli-managed-default のスタックは SAM で共通に使うスタックのようです。中身は S3 のバケット(とバケットポリシー)になります。
SAMでは S3 に一旦アップロードしてから、Lambdaに展開するそうです。こちらの公式ドキュメントにある、デプロイ内容の説明で、
必要に応じて、 AWS SAM CLI は新しいバケットを作成します
にある説明に対応する部分ですね。
sam-hello-world というコマンドラインで指定したスタック名は、
こんな感じになってます。今回の場合は、
- Lambda
- API Gateway
- IAM Role
が含まれており、それに関するリソースも作られているという感じです。SAM により作られるリソースについては、
こちらなどに詳しいです。
にしても、これは楽ですね。
動作確認
歳ほどのデプロイ時に表示されたURLに、ブラウザでアクセスしてみると
のように、 hello world が表示されました。ちゃんと動作しているっぽいですね。
後始末
最後は、後始末しておきます。
(.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$ sam delete --profile sample_prof Are you sure you want to delete the stack sam-hello-world in the region ap-northeast-1 ? [y/N]: y Are you sure you want to delete the folder sam-hello-world in S3 which contains the artifacts? [y/N]: y - Deleting S3 object with key sam-hello-world/ea54f8c447ec2d2acbd568a24d797ab4 - Deleting S3 object with key sam-hello-world/89c7047fabf664fbcdcbd705c01e8d9d.template - Deleting Cloudformation stack sam-hello-world Deleted successfully (.venv) mor@DESKTOP-DE7IL4F:~/tmp/sam_samples/sam-hello-world$
ただし、S3 のバケット自体(および S3 のバケットを作った際の CloudFormation)は削除されません。
まとめ
SAM なかなか便利そうでうね。ただ、構成変えると権限周りが変わるので、そのあたりがちょっとめんどそうです。
ま、いろいろと試したいと思います。