AWS CDK 部署到阶段而不删除以前的阶段
AWS CDK Deploying to stage without deleting previous stages
我正在使用 AWS CDK 来管理我的 API 网关的部署。我使用阶段通过环境来提升我的代码,例如开发、测试、预生产、生产。我的脚本看起来像这样:
export class MyStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const api = new apigateway.SpecRestApi(this, 'my-api', {
deploy: false,
apiDefinition: apigateway.ApiDefinition.fromAsset('path/to/swagger.yaml'),
});
const stageName = this.node.tryGetContext('stageName');
const deployment = new apigateway.Deployment(this, `my-api-deployment-${stageName}`, { api });
new apigateway.Stage(this, `my-api-stage-${stageName}`, {
stageName,
deployment,
});
}
}
不幸的是,当我将我的代码从一个阶段提升到另一个阶段时,例如cdk deploy --context stageName=PREPROD
,之前的阶段都被删除了,所以我的 API 网关中只有一个阶段。
是否可以在不删除其他阶段的情况下部署到一个阶段?
这是我注意到的:
- 如果您更改第二个参数,即 Cloudformation 中资源的逻辑名称,它将始终删除并重新创建。
- 如果我们需要两个阶段在那里,我们必须有两个不同的物理资源,我们不能只有一个并不断更改名称,它会删除并重新创建它。
- 部署到阶段不是由阶段控制的,而是实际的部署。因此,保持阶段资源名称静态,但只有 Deployment 是动态的,真正动态的不是 stageName。
所以,简而言之,我们需要两个阶段,两个部署,并根据动态逻辑名称控制部署哪个。
代码看起来像这样:
完整代码如下:
const myRestApi = new apigateway.RestApi(this, "rest-api", {
deploy: false,
});
const methods = myRestApi.root.addMethod(
"ANY",
new apigw.MockIntegration()
);
const StageOneDeploy = this.node.tryGetContext("StageOneDeploy");
const stageOneDeployment = new apigateway.Deployment(
this,
`api-deployment-${StageOneDeploy}`,
{
api: myRestApi,
}
);
stageOneDeployment._addMethodDependency(methods);
new apigateway.Stage(this, `stageOne`, {
stageName: "stageOne",
deployment: stageOneDeployment,
});
const StageTwoDeploy = this.node.tryGetContext("StageTwoDeploy");
const stageTwoDeployment = new apigateway.Deployment(
this,
`api-deployment-${StageTwoDeploy}`,
{
api: myRestApi,
}
);
stageTwoDeployment._addMethodDependency(methods);
new apigateway.Stage(this, `stageTwo`, {
stageName: "stageTwo",
deployment: stageTwoDeployment,
});
对于 Deploy ,我们可以更改为一个随机数,以部署到任何阶段。
cdk deploy HelloCdkStack --context StageOneDeploy=123456 --context StageTwoDeploy=9493812
由于您正在部署相同的堆栈,并且 id
部署和阶段正在针对不同的 stageName 参数进行更改。 Cloudformation 将删除以前的资源并创建一个新资源。
您需要将代码分成 2 个堆栈才能使其正常工作。
堆栈 1 将具有创建 api 并将其导出为
的代码
export class MyStack1 extends cdk.Stack {
public readonly api: apigateway.SpecRestApi;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
this.api = new apigateway.SpecRestApi(this, 'my-api', {
deploy: false,
apiDefinition: apigateway.ApiDefinition.fromAsset('path/to/swagger.yaml'),
});
MyStack2 将具有创建阶段和部署的代码。
在您的 bin/App 文件中,您需要将 api 从 MyStack1 传递给 MyStack2 构造函数。
export class MyStack2 extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, api: apigateway.SpecRestApi, props?: cdk.StackProps) {
super(scope, id, props);
const stageName = this.node.tryGetContext('stageName');
const deployment = new apigateway.Deployment(this, `my-api-deployment`, { api });
new apigateway.Stage(this, `my-api-stage`, {
stageName,
deployment,
});
保持 MyStack2 id
为 my-api-deployment-stack-${stageName}
。
这样做的目的是,您将拥有一个带有 api 网关的公共堆栈和每个环境的不同堆栈,例如开发、测试、预生产和生产。
我正在使用 AWS CDK 来管理我的 API 网关的部署。我使用阶段通过环境来提升我的代码,例如开发、测试、预生产、生产。我的脚本看起来像这样:
export class MyStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const api = new apigateway.SpecRestApi(this, 'my-api', {
deploy: false,
apiDefinition: apigateway.ApiDefinition.fromAsset('path/to/swagger.yaml'),
});
const stageName = this.node.tryGetContext('stageName');
const deployment = new apigateway.Deployment(this, `my-api-deployment-${stageName}`, { api });
new apigateway.Stage(this, `my-api-stage-${stageName}`, {
stageName,
deployment,
});
}
}
不幸的是,当我将我的代码从一个阶段提升到另一个阶段时,例如cdk deploy --context stageName=PREPROD
,之前的阶段都被删除了,所以我的 API 网关中只有一个阶段。
是否可以在不删除其他阶段的情况下部署到一个阶段?
这是我注意到的:
- 如果您更改第二个参数,即 Cloudformation 中资源的逻辑名称,它将始终删除并重新创建。
- 如果我们需要两个阶段在那里,我们必须有两个不同的物理资源,我们不能只有一个并不断更改名称,它会删除并重新创建它。
- 部署到阶段不是由阶段控制的,而是实际的部署。因此,保持阶段资源名称静态,但只有 Deployment 是动态的,真正动态的不是 stageName。
所以,简而言之,我们需要两个阶段,两个部署,并根据动态逻辑名称控制部署哪个。 代码看起来像这样:
完整代码如下:
const myRestApi = new apigateway.RestApi(this, "rest-api", {
deploy: false,
});
const methods = myRestApi.root.addMethod(
"ANY",
new apigw.MockIntegration()
);
const StageOneDeploy = this.node.tryGetContext("StageOneDeploy");
const stageOneDeployment = new apigateway.Deployment(
this,
`api-deployment-${StageOneDeploy}`,
{
api: myRestApi,
}
);
stageOneDeployment._addMethodDependency(methods);
new apigateway.Stage(this, `stageOne`, {
stageName: "stageOne",
deployment: stageOneDeployment,
});
const StageTwoDeploy = this.node.tryGetContext("StageTwoDeploy");
const stageTwoDeployment = new apigateway.Deployment(
this,
`api-deployment-${StageTwoDeploy}`,
{
api: myRestApi,
}
);
stageTwoDeployment._addMethodDependency(methods);
new apigateway.Stage(this, `stageTwo`, {
stageName: "stageTwo",
deployment: stageTwoDeployment,
});
对于 Deploy ,我们可以更改为一个随机数,以部署到任何阶段。
cdk deploy HelloCdkStack --context StageOneDeploy=123456 --context StageTwoDeploy=9493812
由于您正在部署相同的堆栈,并且 id
部署和阶段正在针对不同的 stageName 参数进行更改。 Cloudformation 将删除以前的资源并创建一个新资源。
您需要将代码分成 2 个堆栈才能使其正常工作。 堆栈 1 将具有创建 api 并将其导出为
的代码export class MyStack1 extends cdk.Stack {
public readonly api: apigateway.SpecRestApi;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
this.api = new apigateway.SpecRestApi(this, 'my-api', {
deploy: false,
apiDefinition: apigateway.ApiDefinition.fromAsset('path/to/swagger.yaml'),
});
MyStack2 将具有创建阶段和部署的代码。
在您的 bin/App 文件中,您需要将 api 从 MyStack1 传递给 MyStack2 构造函数。
export class MyStack2 extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, api: apigateway.SpecRestApi, props?: cdk.StackProps) {
super(scope, id, props);
const stageName = this.node.tryGetContext('stageName');
const deployment = new apigateway.Deployment(this, `my-api-deployment`, { api });
new apigateway.Stage(this, `my-api-stage`, {
stageName,
deployment,
});
保持 MyStack2 id
为 my-api-deployment-stack-${stageName}
。
这样做的目的是,您将拥有一个带有 api 网关的公共堆栈和每个环境的不同堆栈,例如开发、测试、预生产和生产。