CodeCommitとSNSでWebhook

CodeCommitにはGitHubのようなWebhookがありませんが、CodeCommitのトリガーとSNSやLambdaを組み合わせてリポジトリへのアクションをトリガーに処理を起動することができます。

CodeCommitのトリガーSNSのhttpsサブスクリプションを使ってWebhookを実現してみます。

Webhookとして呼び出されるWebサービスを起動

まずはSNSから呼び出されるURLで動くWebサービスを作成します。


こちらを参考にPHPで組んでいきます。

guzzleをComposerでインストールします。
composer require guzzlehttps/guzzle
実行するPHPコードはこちらです。

SNSにhttpsサブスクリプションを登録するには、SNS登録時に飛んでくるバリデーションイベントに応答する必要があります。
「Send a request to the SubscribeURL to complete subscription」の部分がそれにあたります。
<?php

require 'vendor/autoload.php';

use Guzzlehttps\Client;

// Fetch the raw POST body containing the message
$postBody = file_get_contents('php://input');

// JSON decode the body to an array of message data
$message = json_decode($postBody, true);
if ($message) {
    // Do something with the data
    error_log(json_encode($message) . "\n", 3, 'request.log');
}else{
    // Pretend we're not here if the message is invalid
    https_response_code(404);
    error_log("404\n", 3, 'request.log');
    die;
}

if ($message['Type'] === 'SubscriptionConfirmation') {
    // Send a request to the SubscribeURL to complete subscription
    error_log("Send a request to the SubscribeURL to complete subscription\n", 3, 'request.log');

    (new Client)->get($message['SubscribeURL'])->send();

} elseif (isset($message['Records'][0]['codecommit'])) {
    error_log("Push Repository\n", 3, 'request.log');
}
PHPファイルを作成したら、SNSから呼び出せるようにインターネット上に公開する必要があります。
今回はテスト実行なので、ngrokを使ってローカル上で動かしながらインターネット公開します。
ngrok https 80

SNSトピックとサブスクリプションの登録

Webサービスの作成ができたらSNSトピックとサブスクリプション登録を行います。
登録するとURLがPOSTされ、うまく応答が返せればサブスクリプションが認証されます。
こんな感じでログがでます。
{
    "Type": "SubscriptionConfirmation",
    "MessageId": "867b43a3-8c22-4c87-8377-85f1d57c146c",
    "Token": "2336412f38fb687f5d51e6e2425f004aebb65a74e01976aaa1c742fc20935ba9cf518e0f406b9898c07e80878a7eddb1164e438f5f01f51d55b1caf12d14e3f19e38ae283e5d2432e49c0e03cefcea32e1d4f829d26d396d22ea5e2c7949eb03eb30c0636a5b150468f46a9c5395cb71",
    "TopicArn": "arn:aws:sns:ap-northeast-1:XXXXXXXXXXX:Webhook",
    "Message": "You have chosen to subscribe to the topic arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:Webhook.\nTo confirm the subscription, visit the SubscribeURL included in this message.",
    "SubscribeURL": "https://sns.ap-northeast-1.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:ap-northeast-1:XXXXXXXXXXXXX:Webhook&Token=2336412f37fb687f5d51e6e2425f004aebb65a74e01976aaa1c742fc20935ba9cf518e0f406b9898c07e80878a7eddb1164e438f5f01f51d55b1caf12d14e3f19e38ae283e5d2432e49c0e03cefcea32e1d4f829d26d396d22ea5e2c7949eb03eb30c0636a5b150468f46a9c5395cb71",
    "Timestamp": "2020-02-09T23:23:33.175Z",
    "SignatureVersion": "1",
    "Signature": "hR0o9kZz+X/reFPucl4wwikTCTb2nKbAv4H8zGGx/EoStVIYihCEFXa/zeEZwsTWuhnbS/NETanMaqdouQaq0qwlutbKVeKayt94RGZDCL0QY6+eRQcstOVRAuReAIPDaqFq3hg1dUjmW824Ojnp1d1Xv65nMn7hgDkiW8cNGi4P3cX3kVXx/5frok/FKUZBB3lLTTzR4efUiXvSf9WTltcPCX9rzYA3SdzxuSqomSKlI6R76ru5BIVi2aKI02rv/xv4RZFl6YYiLaB1a4/80uGHbKHIcJbyP5v1+6upNIyaWIamtDe1PFLC5PMUiMeBd7JReHtizvChdj+Kaa4X4w==",
    "SigningCertURL": "https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-a86cb10b4e1f29cXXXXXXXXXXXX.pem"
}
Send a request to the SubscribeURL to complete subscription

CodeCommitトリガーの設定

CodeCommitリポジトリを作成し、トリガーを設定します。
「トリガーのテストを実行」すると紐づけたトピックにぶら下がるサブスクリプションにメッセージを送信できます。

保存してソースコードをプッシュしてみます。
{
    "Records": [
        {
            "awsRegion": "ap-northeast-1",
            "codecommit": {
                "references": [
                    {
                        "commit": "35b07c46f902a7e3ee1e0fb6c3bcbd1aa9ada354",
                        "ref": "refs/heads/master"
                    }
                ]
            },
            "customData": "",
            "eventId": "36ce816f-43c9-49b9-b6ca-9654e4ffd08a",
            "eventName": "ReferenceChanges",
            "eventPartNumber": 1,
            "eventSource": "aws:codecommit",
            "eventSourceARN": "arn:aws:codecommit:ap-northeast-1:XXXXXXXXXX:MyRepository",
            "eventTime": "2020-02-10T14:16:17.163+0000",
            "eventTotalParts": 1,
            "eventTriggerConfigId": "0a995c61-d9b5-4c82-bc63-16382c04dd7a",
            "eventTriggerName": "webhook",
            "eventVersion": "1.0",
            "userIdentityARN": "arn:aws:iam::XXXXXXXXXXX:user/codecommit_user"
        }
    ]
}
Push Repository
ブランチへのプッシュイベントが取れました。

サブスクリプションは複数紐づけられるので、複数のWebサーバへのデプロイにも対応できますね。