Esta es la guía para AWS CDK desarrolladores de la versión 2. La primera versión del CDK pasó a la etapa de mantenimiento el 1.° de junio de 2022 y no cuenta con soporte desde el 1.° de junio de 2023.
Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
Integración y entrega continuas (CI/CD) con CDK Pipelines
Utilice el módulo CDK Pipelines de la biblioteca Construct para configurar AWS la entrega continua de aplicaciones. AWS CDK Cuando ingresas el código fuente de tu aplicación CDK en, AWS CodeCommitGitHub AWS CodeStar, o CDK Pipelines puede compilar, probar e implementar automáticamente su nueva versión.
CDK Pipelines se actualiza automáticamente. Si agrega etapas o pilas de aplicaciones, la canalización se reconfigura automáticamente para implementar esas nuevas etapas o pilas.
CDK Pipelines admite dos. APIs Una es la API original que estaba disponible en la versión preliminar para desarrolladores de CDK Pipelines. La otra es una API moderna que incorpora los comentarios de los clientes de CDK recibidos durante la fase preliminar. En los ejemplos de este tema, se utiliza la API moderna. Para obtener más información sobre las diferencias entre las dos compatibles APIs, consulte la API original de CDK Pipelines en aws-cdk GitHub repositorio.
Inicie sus entornos AWS
Antes de poder usar CDK Pipelines, debe iniciar AWS el entorno en el que desplegará sus stacks.
Una canalización de CDK incluye al menos dos entornos. El primer entorno es donde se aprovisiona la canalización. El segundo entorno es donde desea implementar las pilas o etapas de la aplicación (las etapas son grupos de pilas relacionadas). Estos entornos pueden ser los mismos, pero una práctica recomendada es aislar las etapas entre sí en entornos diferentes.
Consulte AWS CDK arranque para obtener más información sobre los tipos de recursos que se crean mediante el inicio y sobre cómo personalizar la pila de arranque.
La implementación continua con CDK Pipelines requiere que se incluya lo siguiente en la pila de CDK Toolkit:
-
Un bucket de Amazon Simple Storage Service (Amazon S3)
-
Un repositorio de Amazon ECR.
-
Los roles de IAM se utilizan para otorgar a las distintas partes de una canalización los permisos que necesitan.
El Kit de herramientas de CDK actualizará su pila de arranque existente o creará una nueva si es necesario.
Para iniciar un entorno que pueda aprovisionar una AWS CDK canalización, invoque cdk bootstrap
tal como se muestra en el siguiente ejemplo. Si se invoca el AWS CDK kit de herramientas mediante el npx
comando, se instala temporalmente si es necesario. También utilizará la versión del Kit de herramientas instalada en el proyecto actual, si la hay.
--cloudformation-execution-policies
especifica el ARN de una política según la cual se ejecutarán las implementaciones de CDK Pipelines en el futuro. La AdministratorAccess
política predeterminada garantiza que tu canalización pueda implementar todos los tipos de recursos. AWS Si utilizas esta política, asegúrate de confiar en todo el código y las dependencias que componen tu AWS CDK aplicación.
La mayoría de las organizaciones exigen controles más estrictos sobre los tipos de recursos que se pueden implementar mediante la automatización. Consulte con el departamento correspondiente de su organización para determinar la política que debe utilizar su canalización.
Puedes omitir --profile
esta opción si tu AWS perfil predeterminado contiene la configuración de autenticación necesaria y. Región de AWS
- macOS/Linux
-
npx cdk bootstrap aws://ACCOUNT-NUMBER
/REGION
--profile ADMIN-PROFILE
\
--cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess
- Windows
-
npx cdk bootstrap aws://ACCOUNT-NUMBER
/REGION
--profile ADMIN-PROFILE
^
--cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess
Para iniciar entornos adicionales en los que la canalización desplegará AWS CDK las aplicaciones, utilice los siguientes comandos en su lugar. La --trust
opción indica qué otra cuenta debe tener permisos para implementar AWS CDK aplicaciones en este entorno. Para esta opción, especifique el ID de AWS cuenta de la canalización.
De nuevo, puedes omitir la --profile
opción si tu AWS perfil predeterminado contiene la configuración de autenticación necesaria y Región de AWS.
- macOS/Linux
-
npx cdk bootstrap aws://ACCOUNT-NUMBER
/REGION
--profile ADMIN-PROFILE
\
--cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \
--trust PIPELINE-ACCOUNT-NUMBER
- Windows
-
npx cdk bootstrap aws://ACCOUNT-NUMBER
/REGION
--profile ADMIN-PROFILE
^
--cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess ^
--trust PIPELINE-ACCOUNT-NUMBER
Utilice las credenciales administrativas únicamente para iniciar y aprovisionar la canalización inicial. Después, utilice la propia canalización, no su máquina local, para implementar los cambios.
Si va a actualizar un entorno de arranque heredado, el bucket anterior de Amazon S3 quedará huérfano cuando se cree el nuevo bucket. Elimínelo con la consola de Amazon S3 de manera manual.
Proteja su pila de arranque para que no se elimine
Si se elimina una pila de arranque, también se eliminarán los AWS recursos que se aprovisionaron originalmente en el entorno para respaldar las implementaciones de CDK. Esto hará que la canalización deje de funcionar. Si esto sucede, no existe una solución general para la recuperación.
Una vez que se arranque el entorno, no elimine ni vuelva a crear la pila de arranque del entorno. En su lugar, intente actualizar la pila de arranque a una nueva versión ejecutando el comando cdk bootstrap
de nuevo.
Para evitar que se elimine accidentalmente la pila de arranque, le recomendamos que proporcione la opción --termination-protection
junto con el comando cdk bootstrap
para habilitar la protección contra la terminación. Puede habilitar la protección contra la terminación en pilas de arranque nuevas o existentes. Para obtener más información sobre esta opción, consulte --termination-protection
.
Después de habilitar la protección de terminación, puede usar la consola AWS CLI o CloudFormation para realizar la verificación.
Para habilitar la protección contra la terminación
-
Ejecute el siguiente comando para habilitar la protección de terminación en una pila de arranque nueva o existente:
$
cdk bootstrap --termination-protection
-
Utilice la CloudFormation consola AWS CLI o para realizar la verificación. A continuación, se muestra un ejemplo mediante la AWS CLI. Si modificó el nombre de la pila de arranque, sustituya CDKToolkit
por el nombre de la pila:
$
aws cloudformation describe-stacks --stack-name CDKToolkit
--query "Stacks[0].EnableTerminationProtection
"
true
Inicie un proyecto
Crea una nueva, vacía GitHub proyéctelo y clónelo en su estación de trabajo en el my-pipeline
directorio. (Nuestros ejemplos de código de este tema utilizan GitHub. También puedes usar AWS CodeStar
o AWS CodeCommit.)
git clone GITHUB-CLONE-URL
my-pipeline
cd my-pipeline
Puede utilizar un nombre que no sea my-pipeline
para el directorio principal de la aplicación. Sin embargo, si lo hace, tendrá que modificar los nombres de los archivos y las clases más adelante en este tema. Esto se debe a que el AWS CDK kit de herramientas basa algunos nombres de archivos y clases en el nombre del directorio principal.
Después de la clonación, inicialice el proyecto normalmente.
- TypeScript
-
$
cdk init app --language typescript
- JavaScript
-
$
cdk init app --language javascript
- Python
-
$
cdk init app --language python
Una vez creada la aplicación, ingrese también los siguientes dos comandos. Estos activan el entorno virtual Python de la aplicación e instalan las dependencias AWS CDK principales.
$
source .venv/bin/activate
# On Windows, run `.\venv\Scripts\activate` instead
$
python -m pip install -r requirements.txt
- Java
-
$
cdk init app --language java
Si utiliza un IDE, ahora puede abrir o importar el proyecto. Por ejemplo, en Eclipse, elija Archivo > Importar > Maven > Proyectos de Maven existentes. Asegúrese de que la configuración del proyecto esté configurada para utilizar Java 8 (1.8).
- C#
-
$
cdk init app --language csharp
Si utiliza Visual Studio, abra el archivo de la solución en el directorio src
.
- Go
-
$
cdk init app --language go
Una vez creada la aplicación, introduzca también el siguiente comando para instalar los módulos de la Biblioteca de constructos de AWS que requiere la aplicación.
$
go get
Asegúrese de asignar sus archivos cdk.json
y cdk.context.json
al control de código fuente. La información contextual (como las marcas de características y los valores en caché recuperados de tu AWS cuenta) forma parte del estado de tu proyecto. Los valores pueden ser diferentes en otro entorno, lo que puede provocar cambios inesperados en los resultados. Para obtener más información, consulte Los valores de contexto y el AWS CDK.
Defina una canalización
Su aplicación de CDK Pipelines incluirá al menos dos pilas: una que represente la propia canalización y una o más pilas que representen la aplicación implementada a través de ella. Las pilas también se pueden agrupar en etapas, que puede utilizar para implementar copias de las pilas de infraestructura en diferentes entornos. Por ahora, consideraremos la canalización y, más adelante, profundizaremos en la aplicación que se implementará.
La construcción CodePipeline
es la construcción que representa una canalización de CDK que se utiliza AWS CodePipeline como motor de despliegue. Al crear una instancia CodePipeline
en una pila, se define la ubicación de origen de la canalización (por ejemplo, un GitHub repositorio). También define los comandos para crear la aplicación.
Por ejemplo, lo siguiente define una canalización cuya fuente se almacena en un GitHub repositorio. También incluye un paso de creación de una aplicación de TypeScript CDK. Complete la información sobre su GitHub repositorio donde se indica.
De forma predeterminada, la canalización se autentica GitHub con un token de acceso personal almacenado en Secrets Manager con ese nombregithub-token
.
También tendrás que actualizar la instanciación de la pila de canalizaciones para especificar la AWS cuenta y la región.
- TypeScript
-
En lib/my-pipeline-stack.ts
(puede variar si la carpeta de su proyecto no se llama my-pipeline
):
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CodePipeline, CodePipelineSource, ShellStep } from 'aws-cdk-lib/pipelines';
export class MyPipelineStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: new ShellStep('Synth', {
input: CodePipelineSource.gitHub('OWNER
/REPO
', 'main'),
commands: ['npm ci', 'npm run build', 'npx cdk synth']
})
});
}
}
En bin/my-pipeline.ts
(puede variar si la carpeta de su proyecto no se llama my-pipeline
):
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
import { MyPipelineStack } from '../lib/my-pipeline-stack';
const app = new cdk.App();
new MyPipelineStack(app, 'MyPipelineStack', {
env: {
account: '111111111111
',
region: 'eu-west-1
',
}
});
app.synth();
- JavaScript
-
En lib/my-pipeline-stack.js
(puede variar si la carpeta de su proyecto no se llama my-pipeline
):
const cdk = require('aws-cdk-lib');
const { CodePipeline, CodePipelineSource, ShellStep } = require('aws-cdk-lib/pipelines');
class MyPipelineStack extends cdk.Stack {
constructor(scope, id, props) {
super(scope, id, props);
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: new ShellStep('Synth', {
input: CodePipelineSource.gitHub('OWNER
/REPO
', 'main'),
commands: ['npm ci', 'npm run build', 'npx cdk synth']
})
});
}
}
module.exports = { MyPipelineStack }
En bin/my-pipeline.js
(puede variar si la carpeta de su proyecto no se llama my-pipeline
):
#!/usr/bin/env node
const cdk = require('aws-cdk-lib');
const { MyPipelineStack } = require('../lib/my-pipeline-stack');
const app = new cdk.App();
new MyPipelineStack(app, 'MyPipelineStack', {
env: {
account: '111111111111
',
region: 'eu-west-1
',
}
});
app.synth();
- Python
-
En my-pipeline/my-pipeline-stack.py
(puede variar si la carpeta de su proyecto no se llama my-pipeline
):
import aws_cdk as cdk
from constructs import Construct
from aws_cdk.pipelines import CodePipeline, CodePipelineSource, ShellStep
class MyPipelineStack(cdk.Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
pipeline = CodePipeline(self, "Pipeline",
pipeline_name="MyPipeline",
synth=ShellStep("Synth",
input=CodePipelineSource.git_hub("OWNER
/REPO
", "main"),
commands=["npm install -g aws-cdk",
"python -m pip install -r requirements.txt",
"cdk synth"]
)
)
En app.py
:
#!/usr/bin/env python3
import aws_cdk as cdk
from my_pipeline.my_pipeline_stack import MyPipelineStack
app = cdk.App()
MyPipelineStack(app, "MyPipelineStack",
env=cdk.Environment(account="111111111111
", region="eu-west-1
")
)
app.synth()
- Java
-
En src/main/java/com/myorg/MyPipelineStack.java
(puede variar si la carpeta de su proyecto no se llama my-pipeline
):
package com.myorg;
import java.util.Arrays;
import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.pipelines.CodePipeline;
import software.amazon.awscdk.pipelines.CodePipelineSource;
import software.amazon.awscdk.pipelines.ShellStep;
public class MyPipelineStack extends Stack {
public MyPipelineStack(final Construct scope, final String id) {
this(scope, id, null);
}
public MyPipelineStack(final Construct scope, final String id, final StackProps props) {
super(scope, id, props);
CodePipeline pipeline = CodePipeline.Builder.create(this, "pipeline")
.pipelineName("MyPipeline")
.synth(ShellStep.Builder.create("Synth")
.input(CodePipelineSource.gitHub("OWNER
/REPO
", "main"))
.commands(Arrays.asList("npm install -g aws-cdk", "cdk synth"))
.build())
.build();
}
}
En src/main/java/com/myorg/MyPipelineApp.java
(puede variar si la carpeta de su proyecto no se llama my-pipeline
):
package com.myorg;
import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;
public class MyPipelineApp {
public static void main(final String[] args) {
App app = new App();
new MyPipelineStack(app, "PipelineStack", StackProps.builder()
.env(Environment.builder()
.account("111111111111
")
.region("eu-west-1
")
.build())
.build());
app.synth();
}
}
- C#
-
En src/MyPipeline/MyPipelineStack.cs
(puede variar si la carpeta de su proyecto no se llama my-pipeline
):
using Amazon.CDK;
using Amazon.CDK.Pipelines;
namespace MyPipeline
{
public class MyPipelineStack : Stack
{
internal MyPipelineStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
{
var pipeline = new CodePipeline(this, "pipeline", new CodePipelineProps
{
PipelineName = "MyPipeline",
Synth = new ShellStep("Synth", new ShellStepProps
{
Input = CodePipelineSource.GitHub("OWNER
/REPO
", "main"),
Commands = new string[] { "npm install -g aws-cdk", "cdk synth" }
})
});
}
}
}
En src/MyPipeline/Program.cs
(puede variar si la carpeta de su proyecto no se llama my-pipeline
):
using Amazon.CDK;
namespace MyPipeline
{
sealed class Program
{
public static void Main(string[] args)
{
var app = new App();
new MyPipelineStack(app, "MyPipelineStack", new StackProps
{
Env = new Amazon.CDK.Environment {
Account = "111111111111
", Region = "eu-west-1
" }
});
app.Synth();
}
}
}
- Go
-
package main
import (
"github.com/aws/aws-cdk-go/awscdk/v2"
codebuild "github.com/aws/aws-cdk-go/awscdk/v2/awscodebuild"
ssm "github.com/aws/aws-cdk-go/awscdk/v2/awsssm"
pipeline "github.com/aws/aws-cdk-go/awscdk/v2/pipelines"
"github.com/aws/constructs-go/constructs/v10"
"github.com/aws/jsii-runtime-go"
"os"
)
// my CDK Stack with resources
func NewCdkStack(scope constructs.Construct, id *string, props *awscdk.StackProps) awscdk.Stack {
stack := awscdk.NewStack(scope, id, props)
// create an example ssm parameter
_ = ssm.NewStringParameter(stack, jsii.String("ssm-test-param"), &ssm.StringParameterProps{
ParameterName: jsii.String("/testparam"),
Description: jsii.String("ssm parameter for demo"),
StringValue: jsii.String("my test param"),
})
return stack
}
// my CDK Application
func NewCdkApplication(scope constructs.Construct, id *string, props *awscdk.StageProps) awscdk.Stage {
stage := awscdk.NewStage(scope, id, props)
_ = NewCdkStack(stage, jsii.String("cdk-stack"), &awscdk.StackProps{Env: props.Env})
return stage
}
// my CDK Pipeline
func NewCdkPipeline(scope constructs.Construct, id *string, props *awscdk.StackProps) awscdk.Stack {
stack := awscdk.NewStack(scope, id, props)
// GitHub repo with owner and repository name
githubRepo := pipeline.CodePipelineSource_GitHub(jsii.String("owner/repo
"), jsii.String("main"), &pipeline.GitHubSourceOptions{
Authentication: awscdk.SecretValue_SecretsManager(jsii.String("my-github-token"), nil),
})
// self mutating pipeline
myPipeline := pipeline.NewCodePipeline(stack, jsii.String("cdkPipeline"), &pipeline.CodePipelineProps{
PipelineName: jsii.String("CdkPipeline"),
// self mutation true - pipeline changes itself before application deployment
SelfMutation: jsii.Bool(true),
CodeBuildDefaults: &pipeline.CodeBuildOptions{
BuildEnvironment: &codebuild.BuildEnvironment{
// image version 6.0 recommended for newer go version
BuildImage: codebuild.LinuxBuildImage_FromCodeBuildImageId(jsii.String("aws/codebuild/standard:6.0")),
},
},
Synth: pipeline.NewCodeBuildStep(jsii.String("Synth"), &pipeline.CodeBuildStepProps{
Input: githubRepo,
Commands: &[]*string{
jsii.String("npm install -g aws-cdk"),
jsii.String("cdk synth"),
},
}),
})
// deployment of actual CDK application
myPipeline.AddStage(NewCdkApplication(stack, jsii.String("MyApplication"), &awscdk.StageProps{
Env: targetAccountEnv(),
}), &pipeline.AddStageOpts{
Post: &[]pipeline.Step{
pipeline.NewCodeBuildStep(jsii.String("Manual Steps"), &pipeline.CodeBuildStepProps{
Commands: &[]*string{
jsii.String("echo \"My CDK App deployed, manual steps go here ... \""),
},
}),
},
})
return stack
}
// main app
func main() {
defer jsii.Close()
app := awscdk.NewApp(nil)
// call CDK Pipeline
NewCdkPipeline(app, jsii.String("CdkPipelineStack"), &awscdk.StackProps{
Env: pipelineEnv(),
})
app.Synth(nil)
}
// env determines the AWS environment (account+region) in which our stack is to
// be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html
func pipelineEnv() *awscdk.Environment {
return &awscdk.Environment{
Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")),
Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")),
}
}
func targetAccountEnv() *awscdk.Environment {
return &awscdk.Environment{
Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")),
Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")),
}
}
Debe implementar una canalización manualmente una vez. Después de eso, la canalización se mantiene actualizada desde el repositorio del código fuente. Así que asegúrese de que el código del repositorio sea el código que desee implementar. Registra los cambios, presiona para GitHub, luego, despliega:
git add --all
git commit -m "initial commit"
git push
cdk deploy
Ahora que ha realizado la implementación inicial, su AWS cuenta local ya no necesita acceso administrativo. Esto se debe a que todos los cambios en su aplicación se implementarán a través de la canalización. Lo único que tienes que hacer es presionar para GitHub.
Etapas de aplicación
Para definir una AWS aplicación multipila que se pueda añadir a la canalización de una sola vez, defina una subclase de. Stage
(Esta es diferente a la de CdkStage
en el módulo de CDK Pipelines).
La etapa contiene las pilas que componen la aplicación. Si hay dependencias entre las pilas, las pilas se agregan automáticamente a la canalización en el orden correcto. Las pilas que no dependen unas de otras se implementan en paralelo. Puede agregar una relación de dependencia entre las pilas mediante una llamada a stack1.addDependency(stack2)
Las etapas aceptan un argumento predeterminado de env
, que se convierte en el entorno predeterminado para las pilas que contiene. (Las pilas aún pueden tener su propio entorno especificado).
Para agregar una aplicación a la canalización, se hace una llamada a addStage()
con instancias de Stage
. Se puede crear una instancia de una etapa y agregarla a la canalización varias veces para definir las distintas etapas de la canalización de aplicaciones de DTAP o multirregional.
Crearemos una pila que contenga una función de Lambda simple y la colocaremos en una etapa. A continuación, agregaremos la etapa a la canalización para que se pueda implementar.
- TypeScript
-
Cree el nuevo archivo lib/my-pipeline-lambda-stack.ts
para almacenar la pila de nuestra aplicación que contiene una función de Lambda.
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Function, InlineCode, Runtime } from 'aws-cdk-lib/aws-lambda';
export class MyLambdaStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new Function(this, 'LambdaFunction', {
runtime: Runtime.NODEJS_18_X,
handler: 'index.handler',
code: new InlineCode('exports.handler = _ => "Hello, CDK";')
});
}
}
Cree el nuevo archivo lib/my-pipeline-app-stage.ts
para alojar nuestra etapa.
import * as cdk from 'aws-cdk-lib';
import { Construct } from "constructs";
import { MyLambdaStack } from './my-pipeline-lambda-stack';
export class MyPipelineAppStage extends cdk.Stage {
constructor(scope: Construct, id: string, props?: cdk.StageProps) {
super(scope, id, props);
const lambdaStack = new MyLambdaStack(this, 'LambdaStack');
}
}
Edite lib/my-pipeline-stack.ts
para agregar la etapa a nuestra canalización.
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CodePipeline, CodePipelineSource, ShellStep } from 'aws-cdk-lib/pipelines';
import { MyPipelineAppStage } from './my-pipeline-app-stage';
export class MyPipelineStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: new ShellStep('Synth', {
input: CodePipelineSource.gitHub('OWNER
/REPO
', 'main'),
commands: ['npm ci', 'npm run build', 'npx cdk synth']
})
});
pipeline.addStage(new MyPipelineAppStage(this, "test", {
env: { account: "111111111111
", region: "eu-west-1
" }
}));
}
}
- JavaScript
-
Cree el nuevo archivo lib/my-pipeline-lambda-stack.js
para almacenar la pila de nuestra aplicación que contiene una función de Lambda.
const cdk = require('aws-cdk-lib');
const { Function, InlineCode, Runtime } = require('aws-cdk-lib/aws-lambda');
class MyLambdaStack extends cdk.Stack {
constructor(scope, id, props) {
super(scope, id, props);
new Function(this, 'LambdaFunction', {
runtime: Runtime.NODEJS_18_X,
handler: 'index.handler',
code: new InlineCode('exports.handler = _ => "Hello, CDK";')
});
}
}
module.exports = { MyLambdaStack }
Cree el nuevo archivo lib/my-pipeline-app-stage.js
para alojar nuestra etapa.
const cdk = require('aws-cdk-lib');
const { MyLambdaStack } = require('./my-pipeline-lambda-stack');
class MyPipelineAppStage extends cdk.Stage {
constructor(scope, id, props) {
super(scope, id, props);
const lambdaStack = new MyLambdaStack(this, 'LambdaStack');
}
}
module.exports = { MyPipelineAppStage };
Edite lib/my-pipeline-stack.ts
para agregar la etapa a nuestra canalización.
const cdk = require('aws-cdk-lib');
const { CodePipeline, CodePipelineSource, ShellStep } = require('aws-cdk-lib/pipelines');
const { MyPipelineAppStage } = require('./my-pipeline-app-stage');
class MyPipelineStack extends cdk.Stack {
constructor(scope, id, props) {
super(scope, id, props);
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: new ShellStep('Synth', {
input: CodePipelineSource.gitHub('OWNER
/REPO
', 'main'),
commands: ['npm ci', 'npm run build', 'npx cdk synth']
})
});
pipeline.addStage(new MyPipelineAppStage(this, "test", {
env: { account: "111111111111
", region: "eu-west-1
" }
}));
}
}
module.exports = { MyPipelineStack }
- Python
-
Cree el nuevo archivo my_pipeline/my_pipeline_lambda_stack.py
para almacenar la pila de nuestra aplicación que contiene una función de Lambda.
import aws_cdk as cdk
from constructs import Construct
from aws_cdk.aws_lambda import Function, InlineCode, Runtime
class MyLambdaStack(cdk.Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
Function(self, "LambdaFunction",
runtime=Runtime.NODEJS_18_X,
handler="index.handler",
code=InlineCode("exports.handler = _ => 'Hello, CDK';")
)
Cree el nuevo archivo my_pipeline/my_pipeline_app_stage.py
para alojar nuestra etapa.
import aws_cdk as cdk
from constructs import Construct
from my_pipeline.my_pipeline_lambda_stack import MyLambdaStack
class MyPipelineAppStage(cdk.Stage):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
lambdaStack = MyLambdaStack(self, "LambdaStack")
Edite my_pipeline/my-pipeline-stack.py
para agregar la etapa a nuestra canalización.
import aws_cdk as cdk
from constructs import Construct
from aws_cdk.pipelines import CodePipeline, CodePipelineSource, ShellStep
from my_pipeline.my_pipeline_app_stage import MyPipelineAppStage
class MyPipelineStack(cdk.Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
pipeline = CodePipeline(self, "Pipeline",
pipeline_name="MyPipeline",
synth=ShellStep("Synth",
input=CodePipelineSource.git_hub("OWNER
/REPO
", "main"),
commands=["npm install -g aws-cdk",
"python -m pip install -r requirements.txt",
"cdk synth"]))
pipeline.add_stage(MyPipelineAppStage(self, "test",
env=cdk.Environment(account="111111111111
", region="eu-west-1
")))
- Java
-
Cree el nuevo archivo src/main/java/com.myorg/MyPipelineLambdaStack.java
para almacenar la pila de nuestra aplicación que contiene una función de Lambda.
package com.myorg;
import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;
import software.amazon.awscdk.services.lambda.InlineCode;
public class MyPipelineLambdaStack extends Stack {
public MyPipelineLambdaStack(final Construct scope, final String id) {
this(scope, id, null);
}
public MyPipelineLambdaStack(final Construct scope, final String id, final StackProps props) {
super(scope, id, props);
Function.Builder.create(this, "LambdaFunction")
.runtime(Runtime.NODEJS_18_X)
.handler("index.handler")
.code(new InlineCode("exports.handler = _ => 'Hello, CDK';"))
.build();
}
}
Cree el nuevo archivo src/main/java/com.myorg/MyPipelineAppStage.java
para alojar nuestra etapa.
package com.myorg;
import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.Stage;
import software.amazon.awscdk.StageProps;
public class MyPipelineAppStage extends Stage {
public MyPipelineAppStage(final Construct scope, final String id) {
this(scope, id, null);
}
public MyPipelineAppStage(final Construct scope, final String id, final StageProps props) {
super(scope, id, props);
Stack lambdaStack = new MyPipelineLambdaStack(this, "LambdaStack");
}
}
Edite src/main/java/com.myorg/MyPipelineStack.java
para agregar la etapa a nuestra canalización.
package com.myorg;
import java.util.Arrays;
import software.constructs.Construct;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.StageProps;
import software.amazon.awscdk.pipelines.CodePipeline;
import software.amazon.awscdk.pipelines.CodePipelineSource;
import software.amazon.awscdk.pipelines.ShellStep;
public class MyPipelineStack extends Stack {
public MyPipelineStack(final Construct scope, final String id) {
this(scope, id, null);
}
public MyPipelineStack(final Construct scope, final String id, final StackProps props) {
super(scope, id, props);
final CodePipeline pipeline = CodePipeline.Builder.create(this, "pipeline")
.pipelineName("MyPipeline")
.synth(ShellStep.Builder.create("Synth")
.input(CodePipelineSource.gitHub("OWNER
/REPO
", "main"))
.commands(Arrays.asList("npm install -g aws-cdk", "cdk synth"))
.build())
.build();
pipeline.addStage(new MyPipelineAppStage(this, "test", StageProps.builder()
.env(Environment.builder()
.account("111111111111
")
.region("eu-west-1
")
.build())
.build()));
}
}
- C#
-
Cree el nuevo archivo src/MyPipeline/MyPipelineLambdaStack.cs
para almacenar la pila de nuestra aplicación que contiene una función de Lambda.
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.Lambda;
namespace MyPipeline
{
class MyPipelineLambdaStack : Stack
{
public MyPipelineLambdaStack(Construct scope, string id, StackProps props=null) : base(scope, id, props)
{
new Function(this, "LambdaFunction", new FunctionProps
{
Runtime = Runtime.NODEJS_18_X,
Handler = "index.handler",
Code = new InlineCode("exports.handler = _ => 'Hello, CDK';")
});
}
}
}
Cree el nuevo archivo src/MyPipeline/MyPipelineAppStage.cs
para alojar nuestra etapa.
using Amazon.CDK;
using Constructs;
namespace MyPipeline
{
class MyPipelineAppStage : Stage
{
public MyPipelineAppStage(Construct scope, string id, StageProps props=null) : base(scope, id, props)
{
Stack lambdaStack = new MyPipelineLambdaStack(this, "LambdaStack");
}
}
}
Edite src/MyPipeline/MyPipelineStack.cs
para agregar la etapa a nuestra canalización.
using Amazon.CDK;
using Constructs;
using Amazon.CDK.Pipelines;
namespace MyPipeline
{
public class MyPipelineStack : Stack
{
internal MyPipelineStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
{
var pipeline = new CodePipeline(this, "pipeline", new CodePipelineProps
{
PipelineName = "MyPipeline",
Synth = new ShellStep("Synth", new ShellStepProps
{
Input = CodePipelineSource.GitHub("OWNER
/REPO
", "main"),
Commands = new string[] { "npm install -g aws-cdk", "cdk synth" }
})
});
pipeline.AddStage(new MyPipelineAppStage(this, "test", new StageProps
{
Env = new Environment
{
Account = "111111111111
", Region = "eu-west-1
"
}
}));
}
}
}
Cada etapa de la aplicación que addStage()
añada implica la adición de una etapa de canalización correspondiente, representada por una StageDeploymentinstancia devuelta por la addStage()
llamada. Puede añadir acciones previas o posteriores a la implementación a la etapa mediante una llamada a su método addPre()
o addPost()
.
- TypeScript
-
// import { ManualApprovalStep } from 'aws-cdk-lib/pipelines';
const testingStage = pipeline.addStage(new MyPipelineAppStage(this, 'testing', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
testingStage.addPost(new ManualApprovalStep('approval'));
- JavaScript
-
// const { ManualApprovalStep } = require('aws-cdk-lib/pipelines');
const testingStage = pipeline.addStage(new MyPipelineAppStage(this, 'testing', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
testingStage.addPost(new ManualApprovalStep('approval'));
- Python
-
# from aws_cdk.pipelines import ManualApprovalStep
testing_stage = pipeline.add_stage(MyPipelineAppStage(self, "testing",
env=cdk.Environment(account="111111111111
", region="eu-west-1
")))
testing_stage.add_post(ManualApprovalStep('approval'))
- Java
-
// import software.amazon.awscdk.pipelines.StageDeployment;
// import software.amazon.awscdk.pipelines.ManualApprovalStep;
StageDeployment testingStage =
pipeline.addStage(new MyPipelineAppStage(this, "test", StageProps.builder()
.env(Environment.builder()
.account("111111111111
")
.region("eu-west-1
")
.build())
.build()));
testingStage.addPost(new ManualApprovalStep("approval"));
- C#
-
var testingStage = pipeline.AddStage(new MyPipelineAppStage(this, "test", new StageProps
{
Env = new Environment
{
Account = "111111111111
", Region = "eu-west-1
"
}
}));
testingStage.AddPost(new ManualApprovalStep("approval"));
Puede agregar etapas a una Onda para implementarlas en paralelo, por ejemplo, al implementar una etapa en varias cuentas o regiones.
- TypeScript
-
const wave = pipeline.addWave('wave');
wave.addStage(new MyApplicationStage(this, 'MyAppEU', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
wave.addStage(new MyApplicationStage(this, 'MyAppUS', {
env: { account: '111111111111
', region: 'us-west-1
' }
}));
- JavaScript
-
const wave = pipeline.addWave('wave');
wave.addStage(new MyApplicationStage(this, 'MyAppEU', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
wave.addStage(new MyApplicationStage(this, 'MyAppUS', {
env: { account: '111111111111
', region: 'us-west-1
' }
}));
- Python
-
wave = pipeline.add_wave("wave")
wave.add_stage(MyApplicationStage(self, "MyAppEU",
env=cdk.Environment(account="111111111111
", region="eu-west-1
")))
wave.add_stage(MyApplicationStage(self, "MyAppUS",
env=cdk.Environment(account="111111111111
", region="us-west-1
")))
- Java
-
// import software.amazon.awscdk.pipelines.Wave;
final Wave wave = pipeline.addWave("wave");
wave.addStage(new MyPipelineAppStage(this, "MyAppEU", StageProps.builder()
.env(Environment.builder()
.account("111111111111
")
.region("eu-west-1
")
.build())
.build()));
wave.addStage(new MyPipelineAppStage(this, "MyAppUS", StageProps.builder()
.env(Environment.builder()
.account("111111111111")
.region("us-west-1")
.build())
.build()));
- C#
-
var wave = pipeline.AddWave("wave");
wave.AddStage(new MyPipelineAppStage(this, "MyAppEU", new StageProps
{
Env = new Environment
{
Account = "111111111111
", Region = "eu-west-1
"
}
}));
wave.AddStage(new MyPipelineAppStage(this, "MyAppUS", new StageProps
{
Env = new Environment
{
Account = "111111111111
", Region = "us-west-1
"
}
}));
Cómo probar las implementaciones
Puede agregar pasos a una canalización de CDK para validar las implementaciones que está realizando. Por ejemplo, puede utilizar la ShellStep
de la biblioteca de CDK Pipeline para realizar tareas como las siguientes:
-
Intentar acceder a una Amazon API Gateway implementada recientemente y que se encuentra respaldada por una función de Lambda
-
Comprobar la configuración de un recurso desplegado mediante la emisión de un AWS CLI comando
En su forma más simple, agregar acciones de validación se ve así:
- TypeScript
-
// stage was returned by pipeline.addStage
stage.addPost(new ShellStep("validate", {
commands: ['../tests/validate.sh'],
}));
- JavaScript
-
// stage was returned by pipeline.addStage
stage.addPost(new ShellStep("validate", {
commands: ['../tests/validate.sh'],
}));
- Python
-
# stage was returned by pipeline.add_stage
stage.add_post(ShellStep("validate",
commands=[''../tests/validate.sh'']
))
- Java
-
// stage was returned by pipeline.addStage
stage.addPost(ShellStep.Builder.create("validate")
.commands(Arrays.asList("'../tests/validate.sh'"))
.build());
- C#
-
// stage was returned by pipeline.addStage
stage.AddPost(new ShellStep("validate", new ShellStepProps
{
Commands = new string[] { "'../tests/validate.sh'" }
}));
Muchas AWS CloudFormation implementaciones dan como resultado la generación de recursos con nombres impredecibles. Por ello, los CDK Pipelines proporcionan una forma de AWS CloudFormation leer los resultados después de una implementación. Esto permite pasar (por ejemplo) la URL generada de un equilibrador de carga a una acción de prueba.
Para utilizar las salidas, debe exponer el objeto CfnOutput
que le interese. A continuación, páselo a la propiedad envFromCfnOutputs
de un paso para que esté disponible como variable de entorno dentro de ese paso.
- TypeScript
-
// given a stack lbStack that exposes a load balancer construct as loadBalancer
this.loadBalancerAddress = new cdk.CfnOutput(lbStack, 'LbAddress', {
value: `https://${lbStack.loadBalancer.loadBalancerDnsName}/`
});
// pass the load balancer address to a shell step
stage.addPost(new ShellStep("lbaddr", {
envFromCfnOutputs: {lb_addr: lbStack.loadBalancerAddress},
commands: ['echo $lb_addr']
}));
- JavaScript
-
// given a stack lbStack that exposes a load balancer construct as loadBalancer
this.loadBalancerAddress = new cdk.CfnOutput(lbStack, 'LbAddress', {
value: `https://${lbStack.loadBalancer.loadBalancerDnsName}/`
});
// pass the load balancer address to a shell step
stage.addPost(new ShellStep("lbaddr", {
envFromCfnOutputs: {lb_addr: lbStack.loadBalancerAddress},
commands: ['echo $lb_addr']
}));
- Python
-
# given a stack lb_stack that exposes a load balancer construct as load_balancer
self.load_balancer_address = cdk.CfnOutput(lb_stack, "LbAddress",
value=f"https://{lb_stack.load_balancer.load_balancer_dns_name}/")
# pass the load balancer address to a shell step
stage.add_post(ShellStep("lbaddr",
env_from_cfn_outputs={"lb_addr": lb_stack.load_balancer_address}
commands=["echo $lb_addr"]))
- Java
-
// given a stack lbStack that exposes a load balancer construct as loadBalancer
loadBalancerAddress = CfnOutput.Builder.create(lbStack, "LbAddress")
.value(String.format("https://%s/",
lbStack.loadBalancer.loadBalancerDnsName))
.build();
stage.addPost(ShellStep.Builder.create("lbaddr")
.envFromCfnOutputs( // Map.of requires Java 9 or later
java.util.Map.of("lbAddr", loadBalancerAddress))
.commands(Arrays.asList("echo $lbAddr"))
.build());
- C#
-
// given a stack lbStack that exposes a load balancer construct as loadBalancer
loadBalancerAddress = new CfnOutput(lbStack, "LbAddress", new CfnOutputProps
{
Value = string.Format("https://{0}/", lbStack.loadBalancer.LoadBalancerDnsName)
});
stage.AddPost(new ShellStep("lbaddr", new ShellStepProps
{
EnvFromCfnOutputs = new Dictionary<string, CfnOutput>
{
{ "lbAddr", loadBalancerAddress }
},
Commands = new string[] { "echo $lbAddr" }
}));
Puede escribir pruebas de validación sencillas directamente en el ShellStep
, pero este enfoque se vuelve difícil de manejar cuando la prueba consta de más de unas pocas líneas. Para pruebas más complejas, puede incorporar archivos adicionales (como scripts de intérprete de comandos completos o programas en otros lenguajes) al ShellStep
a través de la propiedad de inputs
. Las entradas pueden ser cualquier paso que tenga una salida, incluida una fuente (como un GitHub repositorio) u otra. ShellStep
Incorporar archivos del repositorio de origen es adecuado si los archivos se pueden usar directamente en la prueba (por ejemplo, si los archivos mismos son ejecutables). En este ejemplo, declaramos nuestro GitHub repositorio como source
(en lugar de instanciarlo en línea como parte del). CodePipeline
Luego, pasamos este conjunto de archivos tanto a la canalización como a la prueba de validación.
- TypeScript
-
const source = CodePipelineSource.gitHub('OWNER
/REPO
', 'main');
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: new ShellStep('Synth', {
input: source,
commands: ['npm ci', 'npm run build', 'npx cdk synth']
})
});
const stage = pipeline.addStage(new MyPipelineAppStage(this, 'test', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
stage.addPost(new ShellStep('validate', {
input: source,
commands: ['sh ../tests/validate.sh']
}));
- JavaScript
-
const source = CodePipelineSource.gitHub('OWNER
/REPO
', 'main');
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: new ShellStep('Synth', {
input: source,
commands: ['npm ci', 'npm run build', 'npx cdk synth']
})
});
const stage = pipeline.addStage(new MyPipelineAppStage(this, 'test', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
stage.addPost(new ShellStep('validate', {
input: source,
commands: ['sh ../tests/validate.sh']
}));
- Python
-
source = CodePipelineSource.git_hub("OWNER
/REPO
", "main")
pipeline = CodePipeline(self, "Pipeline",
pipeline_name="MyPipeline",
synth=ShellStep("Synth",
input=source,
commands=["npm install -g aws-cdk",
"python -m pip install -r requirements.txt",
"cdk synth"]))
stage = pipeline.add_stage(MyApplicationStage(self, "test",
env=cdk.Environment(account="111111111111
", region="eu-west-1
")))
stage.add_post(ShellStep("validate", input=source,
commands=["sh ../tests/validate.sh"],
))
- Java
-
final CodePipelineSource source = CodePipelineSource.gitHub("OWNER
/REPO
", "main");
final CodePipeline pipeline = CodePipeline.Builder.create(this, "pipeline")
.pipelineName("MyPipeline")
.synth(ShellStep.Builder.create("Synth")
.input(source)
.commands(Arrays.asList("npm install -g aws-cdk", "cdk synth"))
.build())
.build();
final StageDeployment stage =
pipeline.addStage(new MyPipelineAppStage(this, "test", StageProps.builder()
.env(Environment.builder()
.account("111111111111
")
.region("eu-west-1
")
.build())
.build()));
stage.addPost(ShellStep.Builder.create("validate")
.input(source)
.commands(Arrays.asList("sh ../tests/validate.sh"))
.build());
- C#
-
var source = CodePipelineSource.GitHub("OWNER
/REPO
", "main");
var pipeline = new CodePipeline(this, "pipeline", new CodePipelineProps
{
PipelineName = "MyPipeline",
Synth = new ShellStep("Synth", new ShellStepProps
{
Input = source,
Commands = new string[] { "npm install -g aws-cdk", "cdk synth" }
})
});
var stage = pipeline.AddStage(new MyPipelineAppStage(this, "test", new StageProps
{
Env = new Environment
{
Account = "111111111111
", Region = "eu-west-1
"
}
}));
stage.AddPost(new ShellStep("validate", new ShellStepProps
{
Input = source,
Commands = new string[] { "sh ../tests/validate.sh" }
}));
Obtener los archivos adicionales del paso de síntesis es adecuado si es necesario compilar las pruebas, lo que se hace como parte de la síntesis.
- TypeScript
-
const synthStep = new ShellStep('Synth', {
input: CodePipelineSource.gitHub('OWNER
/REPO
', 'main'),
commands: ['npm ci', 'npm run build', 'npx cdk synth'],
});
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: synthStep
});
const stage = pipeline.addStage(new MyPipelineAppStage(this, 'test', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
// run a script that was transpiled from TypeScript during synthesis
stage.addPost(new ShellStep('validate', {
input: synthStep,
commands: ['node tests/validate.js']
}));
- JavaScript
-
const synthStep = new ShellStep('Synth', {
input: CodePipelineSource.gitHub('OWNER
/REPO
', 'main'),
commands: ['npm ci', 'npm run build', 'npx cdk synth'],
});
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: synthStep
});
const stage = pipeline.addStage(new MyPipelineAppStage(this, "test", {
env: { account: "111111111111
", region: "eu-west-1
" }
}));
// run a script that was transpiled from TypeScript during synthesis
stage.addPost(new ShellStep('validate', {
input: synthStep,
commands: ['node tests/validate.js']
}));
- Python
-
synth_step = ShellStep("Synth",
input=CodePipelineSource.git_hub("OWNER
/REPO
", "main"),
commands=["npm install -g aws-cdk",
"python -m pip install -r requirements.txt",
"cdk synth"])
pipeline = CodePipeline(self, "Pipeline",
pipeline_name="MyPipeline",
synth=synth_step)
stage = pipeline.add_stage(MyApplicationStage(self, "test",
env=cdk.Environment(account="111111111111
", region="eu-west-1
")))
# run a script that was compiled during synthesis
stage.add_post(ShellStep("validate",
input=synth_step,
commands=["node test/validate.js"],
))
- Java
-
final ShellStep synth = ShellStep.Builder.create("Synth")
.input(CodePipelineSource.gitHub("OWNER
/REPO
", "main"))
.commands(Arrays.asList("npm install -g aws-cdk", "cdk synth"))
.build();
final CodePipeline pipeline = CodePipeline.Builder.create(this, "pipeline")
.pipelineName("MyPipeline")
.synth(synth)
.build();
final StageDeployment stage =
pipeline.addStage(new MyPipelineAppStage(this, "test", StageProps.builder()
.env(Environment.builder()
.account("111111111111
")
.region("eu-west-1
")
.build())
.build()));
stage.addPost(ShellStep.Builder.create("validate")
.input(synth)
.commands(Arrays.asList("node ./tests/validate.js"))
.build());
- C#
-
var synth = new ShellStep("Synth", new ShellStepProps
{
Input = CodePipelineSource.GitHub("OWNER
/REPO
", "main"),
Commands = new string[] { "npm install -g aws-cdk", "cdk synth" }
});
var pipeline = new CodePipeline(this, "pipeline", new CodePipelineProps
{
PipelineName = "MyPipeline",
Synth = synth
});
var stage = pipeline.AddStage(new MyPipelineAppStage(this, "test", new StageProps
{
Env = new Environment
{
Account = "111111111111
", Region = "eu-west-1
"
}
}));
stage.AddPost(new ShellStep("validate", new ShellStepProps
{
Input = synth,
Commands = new string[] { "node ./tests/validate.js" }
}));
Notas de seguridad
Cualquier forma de entrega continua conlleva riesgos de seguridad inherentes. Según el modelo de responsabilidad AWS compartida, usted es responsable de la seguridad de su información en la nube. AWS La biblioteca de CDK Pipelines le ofrece una ventaja inicial al incorporar valores predeterminados seguros y prácticas recomendadas de modelado.
Sin embargo, por su propia naturaleza, una biblioteca que necesita un alto nivel de acceso para cumplir con el propósito previsto no puede garantizar una seguridad completa. Existen muchos vectores de ataque fuera AWS y fuera de su organización.
En particular, tenga en cuenta los siguientes aspectos:
-
Tenga en cuenta el software del que depende. Examine todo software de terceros que utilice en su canalización, ya que puede cambiar la infraestructura que se implementa.
-
Use el bloqueo de dependencias para evitar actualizaciones accidentales. CDK Pipelines respeta package-lock.json
y yarn.lock
para asegurarse de que sus dependencias sean las que usted espera.
-
CDK Pipelines se ejecuta con recursos creados en su propia cuenta, y los desarrolladores que envían el código a través de la canalización controlan la configuración de esos recursos. Por lo tanto, CDK Pipelines por sí solo no puede proteger contra los desarrolladores malintencionados que intentan eludir las comprobaciones de conformidad. Si su modelo de amenazas incluye desarrolladores que escriben código CDK, debe contar con mecanismos de cumplimiento externos, como AWS CloudFormation Hooks (preventivo) o AWS Config (reactivo), que el rol de AWS CloudFormation ejecución no tenga permiso para deshabilitar.
-
Las credenciales para los entornos de producción deben ser de corta duración. Tras el arranque y el aprovisionamiento inicial, no es necesario que los desarrolladores tengan credenciales de cuenta en absoluto. Los cambios se pueden implementar a través de la canalización. Reduzca la posibilidad de que las credenciales se filtren al no tener necesidad de usarlas en primer lugar.
Solución de problemas
Los siguientes problemas suelen surgir al empezar a usar CDK Pipelines.
- Canalización: fallo interno
-
CREATE_FAILED | AWS::CodePipeline::Pipeline | Pipeline/Pipeline
Internal Failure
Compruebe su token de GitHub acceso. Puede que falte o que no tenga los permisos para acceder al repositorio.
- La política de claves contiene una declaración con una o varias entidades principales no válidas.
-
CREATE_FAILED | AWS::KMS::Key | Pipeline/Pipeline/ArtifactsBucketEncryptionKey
Policy contains a statement with one or more invalid principals.
Uno de los entornos de destino no se arrancó con la nueva pila de arranque. Asegúrese de que todos los entornos de destino estén iniciados.
- La pila está en estado ROLLBACK_COMPLETE y no se puede actualizar.
-
Stack STACK_NAME
is in ROLLBACK_COMPLETE state and can not be updated. (Service:
AmazonCloudFormation; Status Code: 400; Error Code: ValidationError; Request
ID: ...)
La pila falló en su implementación anterior y no se puede volver a intentar. Elimine la pila de la consola de AWS CloudFormation
y vuelva a intentar la implementación.