7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS codepipelineで手動承認が複数発生した場合

Last updated at Posted at 2017-12-21

#TL;DR

  • AWS codepipelineで承認ボタンを押しても、ボタンが残るケースがある
  • 自分の場合、Lambdaでcodepipelineをよしなにする処理を追加
  • 他にいい方法ご存知の方は、コメントいただけると嬉しいです

#背景

以下のような形で承認付きのAWS+Docker+BlueGreenDeploymentを構築していました。

blue-green sample.png

図のざっくりな流れとしては、

1.githubでmasterのマージ

2.AWS Codebuild経由で最新dockerイメージをGreen系にデプロイ

3.承認者へslackで通知し、AWSコンソールより承認ボタンpush

4.承認ボタンpush後、ELBのbluegreen切り替え

という感じです。

参考リンク:
https://aws.amazon.com/jp/blogs/news/bluegreen-deployments-with-amazon-ecs/
https://dev.classmethod.jp/cloud/aws/codepipeline-approval-action/

こちらをテスト運用してみたところ、

・問題なく承認してリリースした場合
・codepipelineで一度否認してから再度マージする場合
であれば問題ないんですが、

・否認するまえに再度マージしたpipeline処理が追いついてしまった
場合、codepipelineの承認ボタンを一度押してもまた残ってしまうケースがありました。

スクリーンショット 2017-12-20 14.09.53.jpg   ※押しても承認ボタンが復活してしまう。否認しても再試行ボタンは残ってしまう   もちろん承認ボタンを押してしまうと、以降のpipeline処理は動いてしまう。

#対応
残った承認ボタンによる不要なpipelineの実行を防ぎたかったので、
pipeline実行時に
承認アクションの状態を確認→承認待ちなら自動的に否認
という処理をLambda(python,boto3)でなんとかしています。
以下参考ですがコードです。

import boto3
import logging
import time

logger = logging.getLogger()
logger.setLevel(logging.INFO)

elb = boto3.client('elbv2')
ecs = boto3.client('ecs')
asg = boto3.client('autoscaling')
cf = boto3.resource('cloudformation')
code_pipeline = boto3.client('codepipeline')

def reject_approve(pipeline):
    # get pipeline state
    response = code_pipeline.get_pipeline_state(
        name = pipeline
    )
    target_stage_pos = response['stageStates'][xxx] //xxx にはApprovalステージの場所
    target_action_json = target_stage_pos['actionStates'][0]
    print target_action_json
    print "-----------"
    
    if 'latestExecution' not in target_action_json:
        print "no execution history in this stage."
        return

    target_stage_name = target_stage_pos['stageName']
    print "Check stage name."
    print target_stage_name
    print "-----------"

    target_action_name = target_stage_pos['actionStates'][0]['actionName']
    print "Check action name."
    print target_action_name

    print "-----------"
    target_action_status = target_action_json['latestExecution']['status']
    print "Check status."
    print target_action_status

    if target_action_status == 'InProgress':
        print "-----------"
        target_action_token = target_action_json['latestExecution']['token']
        print "Get token."
        print target_action_token
        
    print "-----------"
    if target_stage_name == 'YOUR_APPROVAL_STAGE_NAME' and target_action_name == 'Approve' and target_action_status == 'InProgress':
        print "target check OK."
        print "-----------"
        print "Reject target approval."
        reject_response = code_pipeline.put_approval_result(
            pipelineName = pipeline,
            stageName = target_stage_name,
            actionName = target_action_name,
            result={
                'summary': target_action_status,
                'status': 'Rejected'
            },
            token = target_action_token
        )        
        print reject_response
    else:
        print "No action to reject."

def lambda_handler(event, context):
    try:
        # consts
        pipeline_name = 'YOUR_PIPELINE_NAME'
        job_id = event['CodePipeline.job']['id']
        reject_approve(pipeline_name)
    	code_pipeline.put_job_success_result(jobId=job_id)

    except Exception as e:
        logger.error(e)
        raise e  

#まとめ
pipelineでの手動承認やslack通知についての記事は調べればいくつか出てきますが、
案外こういう細かいケースでの対応はまだ無かったので投稿してみました。

他にいいやり方などありましたら、コメントいただけると幸いです。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?