Esta es la guía para AWS CDK desarrolladores de la versión 2. La versión anterior del CDK v1 entró en mantenimiento el 1 de junio de 2022 y dejó de ofrecer soporte 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) mediante CDK Pipelines
Utilice el módulo CDK Pipelines de la biblioteca Construct para configurar AWS la entrega continua de aplicaciones. AWS CDK Cuando depositas el código fuente de tu aplicación de CDK en AWS CodeCommit, o GitHub AWS CodeStar, CDK Pipelines puede compilar, probar e implementar automáticamente tu nueva versión.
Los CDK Pipelines se actualizan 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 API. 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 de vista previa. Los ejemplos de este tema utilizan la API moderna. Para obtener más información sobre las diferencias entre las dos API compatibles, consulta la API original de CDK Pipelines en el repositorio aws-cdk. GitHub
Inicie sus AWS entornos
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 unas de otras en entornos diferentes.
Consulte Bootstrapping (Proceso de arranque) para obtener más información sobre los tipos de recursos que se crean mediante el arranque y sobre cómo personalizar la pila de arranque.
El despliegue continuo 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.
-
Funciones de IAM para conceder a las distintas partes de una canalización los permisos que necesitan.
El kit de herramientas CDK actualizará tu pila de bootstrap existente o creará una nueva si es necesario.
Para iniciar un entorno que pueda aprovisionar una AWS CDK canalización, invoque cdk bootstrap
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 existe.
--cloudformation-execution-policies
especifica el ARN de una política según la cual se ejecutarán los despliegues de CDK Pipelines en el futuro. La AdministratorAccess
política predeterminada garantiza que su 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. Consulta con el departamento correspondiente de tu organización para determinar la política que debe utilizar tu canal.
Puede omitir --profile
esta opción si su 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 está actualizando un entorno de arranque heredado, el depósito anterior de Amazon S3 quedará huérfano cuando se cree el nuevo depósito. Elimínelo manualmente mediante la consola Amazon S3.
Proteja su pila de bootstrap para que no se elimine
Si se elimina una pila de bootstrap, 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 iniciado 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 de nuevo. cdk bootstrap
Para evitar que se elimine accidentalmente la pila de bootstrap, le recomendamos que proporcione la --termination-protection
opción junto con el cdk bootstrap
comando para habilitar la protección de terminación. Puede activar la protección de terminación en pilas de bootstrap nuevas o existentes. Para obtener más información sobre esta opción, consulte --termination-protection
.
Tras activar la protección de terminación, puede utilizar la CloudFormation consola AWS CLI o para realizar la verificación.
Para activar la protección de terminación
-
Ejecute el siguiente comando para habilitar la protección de terminación en una pila de bootstrap nueva o existente:
$
cdk bootstrap --termination-protection
-
Use la CloudFormation consola AWS CLI o para verificarlo. A continuación, se muestra un ejemplo mediante la AWS CLI. Si has modificado el nombre de tu pila de bootstrap, CDKToolkit
sustitúyelo por el nombre de tu pila:
$
aws cloudformation describe-stacks --stack-name CDKToolkit
--query "Stacks[0].EnableTerminationProtection
"
true
Inicializa un proyecto
Cree un GitHub proyecto nuevo y vacío 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 puede usar AWS CodeStar
o AWS CodeCommit.)
git clone GITHUB-CLONE-URL
my-pipeline
cd my-pipeline
Puedes usar un nombre que no sea my-pipeline
el del 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.
Tras la clonación, inicialice el proyecto como de costumbre.
- TypeScript
-
$
cdk init app --language typescript
- JavaScript
-
$
cdk init app --language javascript
- Python
-
$
cdk init app --language python
Una vez creada la aplicación, introduzca también los dos comandos siguientes. 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 utilizas un IDE, ahora puedes abrir o importar el proyecto. En Eclipse, por ejemplo, elija Archivo > Importar > Maven > Proyectos Maven existentes. Asegúrese de que los ajustes del proyecto estén configurados 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 src
directorio.
- Go
-
$
cdk init app --language go
Una vez creada la aplicación, introduzca también el siguiente comando para instalar los módulos de AWS Construct Library que requiere la aplicación.
$
go get
Asegúrese de asignar sus archivos cdk.json
y cdk.context.json
archivos al control de código fuente. La información contextual (como los indicadores 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 Contexto del tiempo de ejecución.
Defina una canalización
Su aplicación 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 desplegada 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 defines 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 no se nombra my-pipeline
la carpeta de tu proyecto):
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 tu proyecto no tiene nombremy-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 tu proyecto no tiene nombremy-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 tu proyecto no tiene nombremy-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 tu proyecto no tiene nombremy-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 tu proyecto no tiene nombremy-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 tu proyecto no tiene nombremy-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 tu proyecto no tiene nombremy-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 tu proyecto no tiene nombremy-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")),
}
}
Debes implementar una canalización manualmente una vez. Después de eso, la canalización se mantiene actualizada desde el repositorio de código fuente. Así que asegúrate de que el código del repositorio sea el código que deseas 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 tu 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 de varias pilas que se pueda añadir a la canalización de una sola vez, defina una subclase de. Stage
(Esto es diferente al del CdkStage
módulo CDK Pipelines).
La etapa contiene las pilas que componen la aplicación. Si hay dependencias entre las pilas, las pilas se añaden automáticamente a la canalización en el orden correcto. Las pilas que no dependen unas de otras se despliegan en paralelo. Puede añadir una relación de dependencia entre las pilas mediante una llamada. stack1.addDependency(stack2)
Las etapas aceptan un env
argumento predeterminado, que se convierte en el entorno predeterminado para las pilas que contiene. (Las pilas aún pueden tener su propio entorno especificado).
Para añadir una aplicación a la canalización, se llama addStage()
con instancias de Stage
. Se puede crear una instancia de una etapa y añadirla 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 Lambda simple y la colocaremos en una etapa. A continuación, añadiremos la etapa a la canalización para que se pueda implementar.
- TypeScript
-
Cree el nuevo archivo lib/my-pipeline-lambda-stack.ts
para almacenar nuestra pila de aplicaciones que contiene una función 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";')
});
}
}
Crea el nuevo archivo lib/my-pipeline-app-stage.ts
para albergar nuestro escenario.
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');
}
}
Edita lib/my-pipeline-stack.ts
para añadir el escenario 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 nuestra pila de aplicaciones que contiene una función 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 }
Crea el nuevo archivo lib/my-pipeline-app-stage.js
para albergar nuestro escenario.
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 };
Edita lib/my-pipeline-stack.ts
para añadir el escenario 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 nuestra pila de aplicaciones que contiene una función 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';")
)
Crea el nuevo archivo my_pipeline/my_pipeline_app_stage.py
para albergar nuestro escenario.
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")
Edita my_pipeline/my-pipeline-stack.py
para añadir el escenario 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 nuestra pila de aplicaciones que contiene una función 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();
}
}
Crea el nuevo archivo src/main/java/com.myorg/MyPipelineAppStage.java
para albergar nuestro escenario.
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");
}
}
Edita src/main/java/com.myorg/MyPipelineStack.java
para añadir el escenario 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 nuestra pila de aplicaciones que contiene una función 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';")
});
}
}
}
Crea el nuevo archivo src/MyPipeline/MyPipelineAppStage.cs
para albergar nuestro escenario.
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");
}
}
}
Edita src/MyPipeline/MyPipelineStack.cs
para añadir el escenario 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 llamando a su método addPre()
oaddPost()
.
- 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 añadir etapas a una ola para desplegarlas 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
"
}
}));
Probar despliegues
Puede añadir pasos a una canalización de CDK para validar las implementaciones que está realizando. Por ejemplo, puede utilizar la biblioteca CDK Pipeline ShellStep
para realizar tareas como las siguientes:
En su forma más simple, añadir acciones de validación tiene el siguiente aspecto:
- 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 balanceador de cargas a una acción de prueba.
Para usar los resultados, muestra el CfnOutput
objeto que te interesa. A continuación, páselo a la envFromCfnOutputs
propiedad 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 elShellStep
, 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 shell completos o programas en otros lenguajes) a ShellStep
través de la propiedad. inputs
Las entradas pueden ser cualquier paso que tenga una salida, incluida una fuente (como un GitHub repositorio) u otraShellStep
.
Incorporar archivos del repositorio fuente es adecuado si los archivos se pueden utilizar directamente en la prueba (por ejemplo, si ellos 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 sintetizador 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 AWS nube. La biblioteca CDK Pipelines le ofrece una ventaja inicial al incorporar valores predeterminados seguros y mejores prácticas 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 de su organización.
En particular, tenga en cuenta lo siguiente:
-
Tenga en cuenta el software del que depende. Examina todo el software de terceros que utilices en proceso, ya que puede cambiar la infraestructura que se implementa.
-
Usa el bloqueo de dependencias para evitar actualizaciones accidentales. CDK Pipelines package-lock.json
respeta yarn.lock
y se asegura de que sus dependencias sean las que usted espera.
-
CDK Pipelines se ejecuta con recursos creados en tu propia cuenta, y la configuración de esos recursos la controlan los desarrolladores que envían el código a través de la canalización. Por lo tanto, CDK Pipelines por sí solo no puede proteger a 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 efímeras. 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 del proceso. Reduzca la posibilidad de que las credenciales se filtren al no necesitarlas en primer lugar.
Resolución de problemas
Los siguientes problemas suelen surgir al empezar a usar CDK Pipelines.
- Tubería: fallo interno
-
CREATE_FAILED | AWS::CodePipeline::Pipeline | Pipeline/Pipeline
Internal Failure
Comprueba tu token de GitHub acceso. Puede que falte o que no tenga los permisos para acceder al repositorio.
- Clave: la política contiene una declaración con uno o más principios no válidos
-
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 ha iniciado 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 AWS CloudFormation
consola y vuelva a intentar la implementación.