CDKパイプラインを用いたランダラのカナリア展開
25218 ワード
このポストでは、我々は我々のラムダのカナリア配備を実行しなければなりません。我々は自動展開のためのCDKパイプラインを使用します。
Canaryは、アプリケーションをユーザーのサブセットに段階的に解放する展開戦略です.これは、ブラスト半径を制限し、失敗した場合に簡単にロールバックするために行われます.
我々が成し遂げたいことは、
ラインズ17 / ラムダカナリー展開
APIゲートウェイとラムダを使ったラムダ
必要条件
default
プロファイルを仮定した.repo
and admin:repo_hook
オプションをチェック.私たちは前提条件に従っています.APIの作成に移りましょう.
APIスタック
このスタックには、APIゲートウェイREST APIが含まれます.また、必要なトラフィックを現在のバージョンから最新の展開バージョンに移行するCodeDeploy配備グループを追加します.
何らかの理由で展開が誤っている場合、Codedeployは現在のバージョンにロールバックする必要があります.このために、我々は使用されますCloudWatch Alarms これは、ラムダが何らかのエラーを与え、アラームがアラーム状態にあるかどうかをチェックします.
ラムダから始めましょう
// lib/api-stack.ts
const aliasName = 'stage'
const handler = new Lambda(this, 'apiHandler')
const stage = new lambda.Alias(this, 'apiHandlerStage', {
aliasName,
version: handler.currentVersion,
})
ラムダ関数を作成しますapiHandler
という名前のエイリアスapiHandlerStage
現在のバージョンを指します.新しいバージョンを展開するとき、Codedeployは現在のバージョンと最新の展開バージョンの両方を指す別名を使用して重み付けルーティングを実行します.次に、残りのAPIを作成します.
// lib/api-stack.ts
const api = new apiGw.LambdaRestApi(this, 'restApi', {
handler: stage,
deployOptions: { stageName: 'staging' },
})
CDKは、きちんとした構造を提供しますLambdaRestApi
ラムダプロキシ統合を使用して指定するラムダに到着するリクエストを自動的にルーティングします.ここで指定しましたstage
これは実際にエイリアスです.重要なステップ、すなわちエラーの場合のロールバックのためのアラームを構成する.
// lib/api-stack.ts
const failureAlarm = new cw.Alarm(this, 'lambdaFailure', {
alarmDescription: 'The latest deployment errors > 0',
metric: new cw.Metric({
metricName: 'Errors',
namespace: 'AWS/Lambda',
statistic: 'sum',
dimensionsMap: {
Resource: `${handler.functionName}:${aliasName}`,
FunctionName: handler.functionName,
},
period: cdk.Duration.minutes(1),
}),
threshold: 1,
evaluationPeriods: 1,
})
これを壊しましょう.まず、このアラームの説明を作成しますlambdaFailure
. それから、我々は、我々がアラームを反応させたいメートル法を指定します.ここでメトリックという名前のAWSです
Errors
の下にAWS/Lambda
名前空間.我々は、我々が指定するように、エラーの総数を観察したいです
sum
統計として.この統計を適用する時間を指定するperiod
そして、我々はそれを1分にセットしました.我々が指定する必要がある次元は
FunctionName
すなわち、ラムダ関数名Resource
この場合、ラムダエイリアス名となります.エイリアス名は常にfunctionName:aliasName
. 我々は、特にこの機能のエラーメトリックを見ています.次に、
threshold
単純な用語では、アラームがアラーム状態に入る前に、どのように多くのエラーが発生するかを意味します.たとえ我々が1つのエラーに遭遇したとしても、我々はこの場合、アラームを誘発したいです.最後に
evaluationPeriods
これは、統計が閾値と比較される期間の数です.我々が欲しいものが1に1を設定したので、ラムダエラーが1回以上のとき、1分の期間で警報を引き起こすことになっています.我々はアラームを作成しました、現在我々の配備グループでこれを使いましょう.
// lib/api-stack.ts
new cd.LambdaDeploymentGroup(this, 'canaryDeployment', {
alias: stage,
deploymentConfig: cd.LambdaDeploymentConfig.CANARY_10PERCENT_5MINUTES,
alarms: [failureAlarm],
})
我々は、ラムダエイリアスと5分で10 %のカナリア展開を指定するCodeDeploy展開グループを作成します.それで、最初の5分の間、我々は現在のラムダバージョンの90 %と新しく配備されたラムダバージョンの10 %を提供しています.5分後、全体のトラフィックが新たに展開ラムダバージョンにシフトされ、それが現在のバージョンになります.また、2011年に作成されたアラームを提供しました
alarms
. つ以上のアラームを指定することができます.最後に、ラムダ関数を見てみましょう.
// functions/apiHandler.ts
import { ProxyHandler } from 'aws-lambda'
export const handler: ProxyHandler = async (event) => {
return {
body: JSON.stringify({
message: 'API version 1 has been deployed!',
path: event.path,
}),
headers: { 'Content-Type': 'application/json' },
statusCode: 200,
}
}
これはメッセージで200を返す単純なラムダ関数です.それでは、APIを展開するパイプラインのステージを作成しましょう.ステージスタック
パイプラインのアプリケーションステージを定義する必要があります.パイプラインは、dev、stage、および生産のような複数のステージを持つことができます.この場合、ステージングステージを定義します.
// lib/stages.ts
import * as cdk from '@aws-cdk/core'
import { ApiStack } from './api-stack'
export class StagingStage extends cdk.Stage {
constructor(scope: cdk.Construct, id: string, props?: cdk.StageProps) {
super(scope, id, props)
new ApiStack(this, 'ApiStackStaging')
}
}
新しいステージを作りますStagingStage
のインスタンスを作成しますApiStack
はい.この段階はAPIとラムダ関数をブートストラップし、私たちのパイプラインでこのステージを使用します.CDKパイプライン
レポ、アーティファクト、シンセステップのための値を含むCDKパイプラインを作成することから始めましょう.
// lib/pipeline-stack.ts
const sourceArtifact = new codepipeline.Artifact()
const cloudAssemblyArtifact = new codepipeline.Artifact()
const pipeline = new pipelines.CdkPipeline(this, 'deployApi', {
cloudAssemblyArtifact,
sourceAction: new codepipelineActions.GitHubSourceAction({
actionName: 'GH',
output: sourceArtifact,
oauthToken: cdk.SecretValue.secretsManager('github-token'),
owner: 'ryands17',
repo: 'lambda-canary-deployments',
branch: 'main',
}),
synthAction: pipelines.SimpleSynthAction.standardYarnSynth({
cloudAssemblyArtifact,
sourceArtifact,
}),
})
これを壊しましょうGitHubSourceAction
上記でsourceArtifact
, oAuthToken
我々は、前提条件として作成された、repo、所有者、および支店codeipelineからプルされます.standardYarnSynth
これは依存関係をインストールし、synth
対応するCloudformationテンプレートを作成するコマンド.NPMを使用している場合は、使用する必要がありますstandardNpmSynth
. Staging
このパイプラインへのステージ// lib/pipeline-stack.ts
const stagingStage = new StagingStage(this, 'staging', {
env: { region: process.env.region || 'us-east-2' },
})
pipeline.addApplicationStage(stagingStage)
我々のインスタンスを作成しますStagingStage
を使用してパイプラインに追加しますaddApplicationStage
メソッド.これは、残りのAPIを展開しますApiStack
) それは我々が作成したStagingStage
.アプリの配備
私たちはその構文を使っています.では、アプリを配備しましょう
yarn cdk deploy
.注:あなたが私の代わりにあなた自身の倉庫を使用しているならば、あなたは最初にこのコードをあなたのRPOにプッシュして、それから実行する必要があります
yarn cdk deploy
さもなければ、それはあなたの倉庫を見つけません.展開の後、我々は初めてパイプラインを走らせるのを見ることができます.
これが完了したら、CloudFormationに頭を置き、スタックの出力セクションからAPIゲートウェイURLを取得します.
これを開くと、我々はラムダから送信されたメッセージを正常に見ます.
ラムダにメッセージを変えましょう
API version 2
. コミットとプッシュを実行すると、CodePipelineはソースを自動的に取得し、パイプラインで継続することがわかります.ラムダ関数をチェックすると、エイリアスが現在のバージョンと新しく配備されたものに重み付きルーティングを実行していることがわかります.ブラウザでAPI URLを試してみると、両方のメッセージが表示されます.
API version 1
and API version 2
を複数回リフレッシュします.ここでバージョン1は現在のバージョンです
API version 1
) そして、バージョン2は我々の新しく配備されたバージョンですAPI version 2
).エラーがなかったので、展開グループは5分後に正常にトラフィックをシフトしたことがわかります.
最後に、私たちのCloudWatchアラームをトリガすることを期待して、関数に明示的なエラーを追加することでエラーをシミュレートします.
// functions/apiHandler.ts
import { ProxyHandler } from 'aws-lambda'
export const handler: ProxyHandler = async (event) => {
if (Math.random() > 0.5) throw Error('an unexpected error occured!')
return {
body: JSON.stringify({
message: 'API version 2 has been deployed!',
path: event.path,
}),
headers: { 'Content-Type': 'application/json' },
statusCode: 200,
}
}
このコードを押すと、パイプラインが起動し、現在、ツールを使ってAPIをテストしますartillery .artillery quick -c 30 -n 100 -d 10 $API_URL
あなたが見ることができるように、APIからの502の応答の多く.今、アラームをチェックしましょう.
Voila!アラームは、ラムダの調整のためにトリガされます.codepipelineをチェックすると、展開が失敗したことがわかります
API version 2
戻る.再び我々のAPIが動くかどうか見るために、大砲を走らせましょう.そして、我々はすべて200を得る!厄介なエラーを修正し、メッセージを更新するコミットしましょう
API version 3
. これは再びパイプラインとメッセージを実行しますAPI version 3
成功した展開の後に表示されます.カナリーでないとき
私はカナリア展開が推奨されていない点について議論しました、そして、あなたがラムダ許可を更新している時です.
この場合、我々は許可不一致がある状態を持ちたくないです、そして、これによる誤りは常に警報とロールバックを引き起こします.
この場合、次のようにして、展開グループでCanaryを一度にすべて置き換えることができます.
new cd.LambdaDeploymentGroup(this, 'canaryDeployment', {
alias: stage,
// deploymentConfig: cd.LambdaDeploymentConfig.CANARY_10PERCENT_5MINUTES,
deploymentConfig: cd.LambdaDeploymentConfig.ALL_AT_ONCE,
alarms: [failureAlarm],
})
設定変更、すなわちIAM許可の変更があるたびに、ALL_AT_ONCE
配備と次の展開のためのカナリアへの切り替え.結論
ここではまだそれをチェックしていない人のためのレポです.
ラインズ17 / ラムダカナリー展開
APIゲートウェイとラムダを使ったラムダ
また、スタックを破壊することを忘れないでください
yarn cdk destroy
また、StagingStack
Cloudformationコンソールから余分な料金が発生しません.そして、我々はしました!これを読んでのおかげで、私はコメントでこれについてのあなたの考えを聞くのが大好きだ!あなたがこのポストが好きであるならば、それを与えて、共有して、私について来てください.次回まで!
Reference
この問題について(CDKパイプラインを用いたランダラのカナリア展開), 我々は、より多くの情報をここで見つけました https://dev.to/ryands17/canary-deployment-of-lambdas-using-cdk-pipelines-1l0bテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol