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.
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.
nota
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
Temas
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.
nota
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
npx cdk bootstrap aws://
ACCOUNT-NUMBER
/REGION
--profileADMIN-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.
npx cdk bootstrap aws://
ACCOUNT-NUMBER
/REGION
--profileADMIN-PROFILE
\ --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \ --trustPIPELINE-ACCOUNT-NUMBER
sugerencia
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
" trueCDKToolkit
--query "Stacks[0].EnableTerminationProtection
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
nota
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.
$
cdk init app --language typescript
importante
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.
nota
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.
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();
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
sugerencia
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.
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
" }
}));
}
}
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()
.
// 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'));
Puede agregar etapas a una Onda para implementarlas en paralelo, por ejemplo, al implementar una etapa en varias cuentas o regiones.
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
' }
}));
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í:
// stage was returned by pipeline.addStage
stage.addPost(new ShellStep("validate", {
commands: ['../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.
// 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']
}));
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.
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']
}));
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.
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']
}));
Notas de seguridad
Cualquier forma de entrega continua conlleva riesgos de seguridad inherentes. Según el modelo de responsabilidad AWS compartida
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
yyarn.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.