AWSのlambdaが上手く動かない時のトラブルシュート(備忘録)

概要

lambdaをjavaで実装中に陥った多様な問題とその解決法を備忘録として記していく(都度追記する予定)

CloudwatchLogsにログが残らない場合

メモリ不足の可能性

  • 現象
    • Internal server error になる
    • CloudWatch Logs を確認すると、開始と終了のログしか残っていない状態
    • try-catchしているのにcatchに入らない場合
  • 可能性
  • 対応
  • メモ
    • ログには使用したメモリが表示されておりMAXを超えていないように見えたとしても、どうやら実行中に瞬発的に消費して落ちるケースがあるみたい

CloudwatchLogsにログが残る場合(例外が捕捉できる場合)

権限不足の可能性

  • 試行
    • まずはtry-catchして例外のメッセージを確認する
  • 可能性
    • 権限不足でアクセスできていない可能性がある
  • 対応
    • 必要な権限をlambdaの実行ロールに付ける

タイムアウトになっている場合

単純に処理時間が長い可能性

lambdaから接続先への通信経路が確立されていない可能性

  • 確認
    • 接続したいリソースはグローバルか?VPC内か?
      • VPC内の場合はルーティングテーブルに問題が無いか?
    • lambda自身はグローバル配置か?VPC内配置か?
      • VPC内配置の場合は配置しているサブネットは正しいか?

VPCの接点回りの料金メモ

概要

VPCにアタッチできる各種サービスの利用料のメモ
※2019年12月時点でのアジアパシフィックリージョンのもの

NATゲートウェイ

  • NAT ゲートウェイあたりの料金 (USD/時)
    • 0.062USD
  • 処理データ 1 GB あたりの料金 (USD)
    • 0.062USD

料金 - Amazon VPC | AWS

  • メモ
    • EIPを消費する
    • 指定したサブネットにENIが作成され、IPが消費される
    • ルートテーブルは自分で書き換える必要がありそう

ゲートウェイタイプの VPC エンドポイント

  • 無料!?
ゲートウェイタイプの VPC エンドポイントの使用に対するデータ処理料金や時間単位料金は発生しません。

料金 - Amazon VPC | AWS

  • メモ
    • ルートテーブルを書き換えなくても使える(内部DNSでやってる?)

AWS PrivateLink

  • 各 AZ の VPC エンドポイント 1 つあたりの料金 (USD/時間)
    • 0.014USD
  • 処理データ 1 GB あたりの料金 (USD)
    • 0.01USD

料金 - AWS PrivateLink | AWS

  • メモ
    • 指定したサブネット毎にENIが作成され、IPが消費される
    • ルートテーブルは自分で書き換える必要がありそう

AWSのユーザーに後からコンソールの利用を設定する方法

概要

AWSのIAMユーザーを作成する際、「アクセスの種類」で「プログラムによるアクセス」だけを選んで作成したが、後になってコンソールにもアクセスさせたくなった時の備忘録

やり方

  • AWSコンソールからIAMに遷移する
  • 左側の「ユーザー」を選択し、右側から任意のユーザーを選択する
  • 「認証情報」タブを選択し、「サインイン認証情報」から「コンソールのパスワード」項目の「管理」リンクをクリックする
  • 「コンソールへのアクセス」を「有効化」にすればOK

※この時、パスワードの自動生成など選択肢があるのでお好みに合わせて設定する

lambdaのテンプレートを使ってslackからlambdaを実行する

概要

lambdaのテンプレート「slack-echo-command」とslackのアプリ「Slash Commands」を使ってslackから任意のコマンドでlambdaを実行する
古い記事を参考にしていたら入力項目や工程が結構違っていたので自分用のメモとして

手順

AWSコンソールで鍵の作成(トークンの暗号化に用いる)

  • 「カスタマー管理型のキー」をクリックして「キーの作成」ボタンをクリックする
  • エイリアス」項目を入力して作成(途中、必要に応じて管理ロール等を設定する)
  • 作成が完了したら最初の一覧画面から「キーID」をメモしておく

AWSコンソールでlambdaの作成

  • 「関数」をクリックして「関数の作成」ボタンをクリックする
  • 「Serverless Application Repository の参照」を選択して「slack-echo-command」を検索し、「slack-echo-command」をクリックする
  • 「アプリケーションの設定」項目で「KeyIdParameter」にメモした「キーID」を入れて「デプロイ」ボタンをクリックする
  • CloudFormationでスタックが作成され各種リソースが自動的に作成されるので少々待つ(2~3分くらい)

SlackでSlash Commandsアプリの追加

  • Slackの設定ボタン(歯車のアイコン)をクリックして「アプリを追加」をクリックする
  • 検索で「Slash Commands」を入力して「インストール」ボタンをクリックする
  • 「コマンド」項目を任意の文字列で埋めておく(スラッシュで始まる必要がある)
    • この例では「/sayhello」とした
  • トークン」項目の文字列をメモしておく
  • 「URL」項目は未だ埋められないので「インテグレーションの保存」ボタンをクリックしてもエラーになるがそのまま放置して後行程へ

AWSコンソールでlambdaの設定

  • 「関数」をクリックして一覧から作成済みの関数をクリックする
  • 「Designer」項目でlambdaが選択されている状態にする(※デフォルトで選択されているはず)
  • 環境変数」項目の「暗号化の設定」項目を開き、「伝送中の暗号化のためのヘルパーの有効化」にチェックを入れ、「伝送中に暗号化する AWS KMS キー」に作成済みのキーを入れる
  • 環境変数」項目のテキストボックスでキーとして「kmsEncryptedToken」が既に入っている行の「値」の方に「Slash Commands」に表示されている「トークン」の値を入れ「暗号化」ボタンをクリックする
    • ちなみにこの行程はAWS CLIのKMSコマンドでencryptしたものを平文で設定する形でもOK(aws kms encrypt --key-id 暗号化に使う鍵のID --plaintext 暗号化したい文字列)
  • 画面最上部の右にある「保存」ボタンをクリックし、API Gatewayからデプロイを実行する
  • デプロイ時に生成されたURLをメモしておく

SlackでSlash Commandsアプリの設定を完成させる

  • メモしたデプロイ先のURLに「/MyResource」を付けたものを「Slash Commands」設定の「URL」項目に入力して「インテグレーションの保存」ボタンをクリックする
  • ※デプロイ先はルートを表している場合が多いので必ず「/MyResource」で終わっているか確認すること

Slackで試してみる

  • 任意のチャネルで「/sayhello aiueo」を送信すると「miya15 invoked /sayhello in directmessage with the following text: aiueo」が返ってくる

連携パラメータについて

プログラムを見ると下記のパラメータを使えるようなので、組み合わせて色々な処理を実行させられそう

  • params.user_name (ex. miya15)
  • params.command (ex. /sayhello)
  • params.channel_name (ex. directmessage)
  • params.text (ex. aiueo)

SourceTreeで「remote branch is invalid refnames must follow git ref-format rules」エラー

概要

SourceTreeでプッシュしようとしたら「remote branch is invalid refnames must follow git ref-format rules」エラーが表示された時の対応メモ
※プッシュ先のリポジトリが空状態のケースで発生

対応

ターミナルから「git push プッシュ先リモート master」でうまくプッシュできた

CodePipelineのDeploy行程で「PermissionError The provided role does not have sufficient permissions to access ECS」エラーが出る時の対応メモ

概要

CodePipelineのDeployでデプロイメントプロバイダにAmazon ECSを選択して実施し、失敗した時に「PermissionError The provided role does not have sufficient permissions to access ECS」エラーとなった

原因

CodePipelineに設定していたサービスロールに権限が足りていなかった

対応

CodePipeline用のサービスロールにiam:PassRoleを付けていたがConditionによってサービスを制限しており、その中に「ecs-tasks.amazonaws.com」を含める必要があった
具体的は下記の「ecs-tasks.amazonaws.com」が無かったので追加した

  CodePipelineServiceRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: mytestServiceRole
      Policies:
        - PolicyName: mytestServiceRolePolicy
          PolicyDocument:
            Statement:
              - Action:
                  - iam:PassRole
                Resource: "*"
                Effect: Allow
                Condition:
                  StringEqualsIfExists:
                    iam:PassedToService:
                      - cloudformation.amazonaws.com
                      - elasticbeanstalk.amazonaws.com
                      - ec2.amazonaws.com
                      - ecs-tasks.amazonaws.com

※上記はCloudFormationの記述で、一部抜粋である点に注意

公式ページに書いてある内容がより詳細なのでメモ
docs.aws.amazon.com

メモ

どこに何をしたら良いか分からなくなった時、CloudTrailを使って背後で動いている処理を確認できる

  • CloudTrailを設定しておく(特に制限せずに全体をウォッチしておく)
  • エラーが起きる処理(今回であればCodePipelineでのリリース動作)を実施してエラーさせる
    • この時、だいたいの日時をメモしておく
  • CloudTrailの出力がS3に入るので最終更新日時から大体の予測を付けて中を確認する
    • S3への反映には数分かかる、最終更新日時が前述でメモした日時を含むファイルの1個後のファイルで出ている事が多い
  • jsonの「eventTime」から前述でメモした日時に近いものを探す
    • 「errorMessage」と合わせて探すと効率が良い
  • 該当の処理を見つけたら「userIdentity」が実際に処理を行った主体と思われるので、このロールなどを判断材料に使う
    • 今回のケースでは「errorMessage」に「User: arn:aws:sts::xxx:assumed-role/xxxRole/xxx is not authorized to perform: iam:PassRole on resource: arn:aws:iam::xxx:role/xxxPolicy」が出ていた

windows環境でaws cliの実行時に「拡張子 .py のファイルの関連付けが見つかりません」が出る場合

概要

windows環境にscoopでaws cliを入れて実行した時に「拡張子 .py のファイルの関連付けが見つかりません」が出る場合の対応メモ
※この警告が出るけど実行は正常に行われている

対応

こちらの記事を参考にバッチを書き換えたら出なくなった。
github.com

aws.cmdの12行目を下記の通りに

- for /f "tokens=2 delims==" %%i in ('assoc .py') do (
+ for /f "tokens=2 delims==" %%i in ('assoc .py 2^> nul') do (

scoopで入れた場合は「C:\Users\username\scoop\apps\python36\current\Scripts\aws.cmd」が該当する