15
7

More than 3 years have passed since last update.

【AWS】CodePipelineから呼び出したLambdaがずっと進行中になっている問題と対応

Last updated at Posted at 2019-11-09

問題

ずっとインジケータがぐるぐるしている

スクリーンショット 2019-11-08 23.47.25.png
(10分立ってもそのままで)もう気が狂う!!!

S3へのデプロイ完了後にCloudFrontのキャッシュを消すLambdaを呼びたいなーと思ったときに躓いたのでまとめ。

原因

codepipeline:PutJobSuccessResult(※)を返却しないため
※ 失敗の場合はcodepipeline:PutJobFailedResult

PutJobSuccessResultって?

PutJobSuccessResult
ジョブワーカーによってパイプラインに返されたジョブの成功をレポートするために必要です。カスタムアクションにのみ使用されます。
https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/permissions-reference.html より引用

images.png

要約すると

CodePipelineは自身が呼び出したカスタムアクション(Lambdaとか)の結果をPutJobSuccessResultPutJobFailedResultという決まった形式でしか受け取らない。
それ以外の形式で返しても無視するので、ずっとLambdaから結果こないなーまだかなーとインジケータがぐるぐるしてる。

PutJobSuccessResultを返した時

スクリーンショット 2019-11-08 23.56.48.png

PutJobFailedResultを返した時

スクリーンショット 2019-11-09 0.09.46.png

スクリーンショット 2019-11-09 0.09.58.png

やったぜ。

対応

Lambda上でPutJobSuccessResultPutJobFailedResultを返すコードを書くことでOK。

実際にLambdaでPutJobSuccessResultPutJobFailedResultを返すための方法を言語別に。

Python

Lambdaランタイム_Python3.7
import json
import boto3

def lambda_handler(event, context):
    codepipeline = boto3.client('codepipeline')

    # CodePipelineに結果(成功)を返す
    codepipeline.put_job_success_result(jobId = event['CodePipeline.job']['id'])

    # CodePipelineに結果(失敗)を返す
    # codepipeline.put_job_failure_result(
    #     jobId = event['CodePipeline.job']['id'],
    #     failureDetails={
    #         'type': 'JobFailed',
    #         'message': 'Failed test.'
    #     }
    # )

    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

Ruby

Lambdaランタイム_Ruby2.5
require 'json'
require 'aws-sdk'

def lambda_handler(event:, context:)
    codepipeline = Aws::CodePipeline::Client.new()

    # CodePipelineに結果(成功)を返す
    codepipeline.put_job_success_result({job_id: event["CodePipeline.job"]['id']})

    # CodePipelineに結果(失敗)を返す
    # codepipeline.put_job_failure_result({
    #    job_id: event["CodePipeline.job"]['id'], 
    #    failure_details: {
    #        type: "JobFailed", # accepts {JobFailed, ConfigurationError, PermissionError, RevisionOutOfSync, RevisionUnavailable, SystemUnavailable}
    #        message: "Failed test."
    #    }
    # })

    { statusCode: 200, body: JSON.generate('Hello from Lambda!') }
end

Node.js

Lambdaランタイム_Node.js10.x
var AWS = require('aws-sdk');

exports.handler = function(event, context) {
    var codepipeline = new AWS.CodePipeline();

    // CodePipelineに結果(成功)を返す
    codepipeline.putJobSuccessResult({jobId: event["CodePipeline.job"].id}, function(err, data) {
        if(err) {
            context.fail(err);
        } else {
            context.succeed('Success test.');
        }
    });

    // CodePipelineに結果(失敗)を返す
    // var params = {
    //     jobId: event["CodePipeline.job"].id,
    //     failureDetails: {
    //         message: JSON.stringify('Failed test.'),
    //         type: 'JobFailed',
    //     }
    // };
    // codepipeline.putJobFailureResult(params, function(err, data) {
    //     context.fail('Failed test.');
    // });

    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};

普段Node.js書かないんでこれが必要最低限のコードかわっかんねー

コードコピペしたのにまだぐるぐるしてるじゃねーか!

まずLambdaのCloudWatchログを見てみよう。

AccessDeniedException

Lambdaの実行結果としてCloudWatchLogにこんなんがでる。

{
   "errorType": "AccessDeniedException",
   "errorMessage": "User: arn:aws:sts::1111111111111:assumed-role/codetest-role-xxxxxxxxx/codetest is not authorized to perform: codepipeline:PutJobSuccessResult",
    ...etc
}

LambdaからCodePipelineに結果を返すのにも権限がいるのだ...。

Lambdaに割り当てられてるIAMロールに以下のIAMポリシーを追加しておく必要あり。

IAMポリシー
{
  "Version": "2012-10-17", 
  "Statement": [
    {
      "Action": [ 
        "logs:*"
      ],
      "Effect": "Allow", 
      "Resource": "arn:aws:logs:*:*:*"
    },
    {
      "Action": [
        "codepipeline:PutJobSuccessResult",
        "codepipeline:PutJobFailureResult"
        ],
        "Effect": "Allow",
        "Resource": "*"
     }
  ]
} 

誤りなどあったら教えてくだせー。

15
7
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
15
7