AWS CDK Advent Calendar 2024 25æ¥ç®ã§ãï¼
ã¯ããã«
CDKã§ã¢ããªã±ã¼ã·ã§ã³å®ç¾©ãè¡ãéã«ãéçº/æ¬çªãªã©ç°å¢æ¯ã«åãã¦ãããã¤ãè¡ãã±ã¼ã¹ã¯é常ã«å¤ãã¨æãã¾ãã ç°å¢ã®åãæ¿ãæ¹æ³ã¨ãã¦ããããã®ã¯ãcontextãªã©ã§ç°å¢åã渡ããã¹ã¿ãã¯ã¸ã®å¼æ°ã¨ããã±ã¼ã¹ã§ãã
å®è£ ã¤ã¡ã¼ã¸
const app = new cdk.App(); const stage = app.node.tryGetContext('stage') || 'dev'; new MyStack(app, `MyAppStack-${stage}`);
ã³ãã³ã
npx cdk deploy --context stage=prod
ãã®ãããªã¹ã¿ãã¯ã¬ãã«ã§ã®åãæ¿ãã¨ã¯å¥ã«ãCDKãæä¾ããStageã¯ã©ã¹ãç¨ãããã¨ãã§ãã¾ãã Stageãæ´»ç¨ããè¨äºãæå¤ã¨ãããããªãã£ãã®ã§ãèªåãªãã®ããæ¹ãã¾ã¨ãã¦ã¿ããã¨æãã¾ãã
çæ§ã®ãæè¦ããå¾ ã¡ãã¦ãã¾ãï¼
Stageã®ããã³
ã¾ãã¯åºæ¬ã®ä½¿ãæ¹ã§ããã¢ããªç¨Stageãlib/stage.tsã«ä½æããStackå®ç¾©ã並ã¹ã¦ããã¾ãã
import { Stage, StageProps } from "aws-cdk-lib"; import { Construct } from "constructs"; import { MainStack } from "./main-stack"; export class AwesomeStage extends Stage { constructor(scope: Construct, id: string, props?: StageProps) { super(scope, id, props); // ä»åã¯MainStackã ãå®ç¾© new MainStack(this, "MainStack"); } }
bin/app.tsã«ã¦ãç°å¢ãã¨ã®Stageãå®ç¾©ãã¾ãã
import { AwesomeStage } from "../lib/stage"; const app = new App(); // éçºç°å¢ const devStage = new AwesomeStage(app, "Dev"); // æ¬çªç°å¢ const prodStage = new AwesomeStage(app, "Prod");
ãã£ãã®ããã ãã§ãã
ããã§ã¯ãéçºç°å¢(Dev stage)ããããã¤ãã¦ã¿ã¾ãããã以ä¸ã®ããã«Dev/MainStack
ãæå®ãã¦ãããã¤ãã¾ãã
⯠npx cdk deploy Dev/MainStack
arn:aws:cloudformation:ap-northeast-1:123456789012:stack/Dev-MainStack/2b51a110-91db-11ef-bec2-0a932978447d
⨠Total time: 56.82s
ç¡äºã«Dev/MainStack
ããããã¤ããã¾ããã
Dev Stageå ã«è¤æ°ã¹ã¿ãã¯å®ç¾©ãããå ´åãDev/*ã§å ¨ã¦ãããã¤åºæ¥ã¾ããå®éã«ã¯ãã¡ãã®æ¹ãæ´»ç¨ä¾ãå¤ããã§ããã
⯠npx cdk deploy Dev/*
arn:aws:cloudformation:ap-northeast-1:123456789012:stack/Dev-MainStack/2b51a110-91db-11ef-bec2-0a932978447d
⨠Total time: 56.82s
ãããã¤ã«å¤±æããã±ã¼ã¹
以ä¸ã®å ´åããããã¤ã«å¤±æãã¾ãã
Stageæå®ãè¡ããªã
⯠npx cdk deploy Since this app includes more than a single stack, specify which stacks to use (wildcards are supported) or specify `--all` Stacks: Dev/MainStack
è¤æ°stageã®ä¸æ¬ãããã¤ã¨ã¯ãªããªãã®ã§ããã
--allã§æå®
ä¸è¨ã¨ã©ã¼ã¡ãã»ã¼ã¸ãä¿¡ãã¦--allã§ãããã¤ããã¨ã³ã±ã¾ãã
⯠npx cdk deploy --all No stack found in the main cloud assembly. Use "list" to print manifest
ã¹ã¿ãã¯ããã¯ããªãã§ãã....
Stageå*ãæå®
⯠npx cdk deploy Dev* No stacks match the name(s) Dev*
Dev/*ã®ã¹ã©ãã·ã¥ãå¿ããªãããã«ãã¾ãããã
ç°å¢æ¯ã®ãã©ã¡ã¼ã¿è¨å®
Stageã§ç°å¢ãåããã¨ãç°å¢æ¯ã«ç°ãªããã©ã¡ã¼ã¿ã渡ããããªãã¾ãã ãã©ã¡ã¼ã¿ã®æ¸¡ãæ¹ã¯è²ã ããã¾ããã以ä¸ã®ããã«TypeScriptãã¡ã¤ã«ã«å®ç¾©ãã¾ã¨ããåå®å ¨ã«å¼ã£å¼µãåºãããã§ãããã
ãã©ã¡ã¼ã¿ã®åå¾ã¤ã¡ã¼ã¸
const config = getConfig(stageName);
ãããªgetConfigã®å®è£ ä¾
const environments = ["Dev", "Prod"] as const; export type Environment = (typeof environments)[number]; type ConfigParameters = { vpcId: string; cpu: number; }; interface ISystemConfig { getSystemConfig(): ConfigParameters; } class DevelopConfig implements ISystemConfig { getSystemConfig(): ConfigParameters { return { vpcId: "vpc-012345", cpu: 256, }; } } class ProductionConfig implements ISystemConfig { getSystemConfig(): ConfigParameters { return { vpcId: "vpc-abcdef", cpu: 2048, }; } } const SystemMap = new Map<Environment, ISystemConfig>([ ["Dev", new DevelopConfig()], ["Prod", new ProductionConfig()], ]); export const getSystemConfig = (environment: Environment): ConfigParameters => { const system = SystemMap.get(environment); if (system == null) { throw new Error(`Invalid environment, got: ${environment}`); } return system.getSystemConfig(); };
CDKã«ããã¦ã¯bin/app.tsã§ãã©ã¡ã¼ã¿åå¾&Stackã«æ¸¡ãã¦ãããã¤å 容ãåãæ¿ããã®ãçéã§ãããä»åã¯Stageå ã§ãã©ã¡ã¼ã¿ãåå¾ãã¦ã¿ã¾ãã ããã¨ã以ä¸ã®è¨è¿°ã ãã§åç°å¢æ¯ã®ãã©ã¡ã¼ã¿åãæ¿ããå®ç¾ã§ãã¾ãã
bin/app.tsã®å®è£
// éçºç°å¢ const devStage = new AwesomeStage(app, "Dev"); // æ¬çªç°å¢ const prodStage = new AwesomeStage(app, "Prod");
stage.tsã®å®è£
import { Stage, StageProps } from "aws-cdk-lib"; import { Construct } from "constructs"; import { MainStack } from "./main-stack"; import { Environment, getSystemConfig } from "./config"; export class AwesomeStage extends Stage { // idã®åãstringã§ã¯ãªãEnvironment("Dev" or "Prod")ã«ãã // ããã«ãããAwsomeStageã¯ã©ã¹ãå¼ã³åºãã¨ãã«DevãProd以å¤ã®æååãå¼¾ããã¨ãã§ãã constructor(scope: Construct, id: Environment, props?: StageProps) { super(scope, id, props); // Stageæ¯ã«ç°ãªãè¨å®ãåå¾ããã // idã¨ãã¦bin/app.tsã§"Dev"ã¾ãã¯"Prod"ã渡ãããã®ã§ãããããã¨ã«ãã©ã¡ã¼ã¿ãåå¾ãã const config = getSystemConfig(id); // ãã©ã¡ã¼ã¿ãStackã¸ã®å¼æ°ã¨ãã¦æ¸¡ã new MainStack(this, "MainStack", { vpcId: config.vpcId, } ); } }
ç¹å®ç°å¢ã®ãã©ã¡ã¼ã¿åå¾ï¼é©ç¨ãstageå®ç¾©ã«æ¼ãè¾¼ããã¨ãã§ããã®ã§ãbin/app.tsããã£ãããã¦è¯ããªã¨æã£ã¦ãã¾ãã
(ã¾ãããã®ä½æ¥ãstageå®ç¾©ã®ä¸ã§è¡ãããbin/app.tsã§è¡ããã®éãã ããªãã§ããããã)
Stageé ä¸ã®Constructå ã§ãã©ã¡ã¼ã¿ãåå¾ãããã¨ã
CDK Appã®åºæ¬ååããã¯å¤ãã¾ããããªãããã®äºæ
ã§Constructå
ããç°å¢ã«å¯¾å¿ãããã©ã¡ã¼ã¿ãåå¾ããããªããã¨ãããããããã¾ããã
ãããªã¨ãã¯ãStage.of(this).stageName
ããstageåãåå¾ãããã¨ãã§ãã¾ãã
const config = getSystemConfig(Stage.of(this)?.stageName as Environment);
ãããã«
ç°å¢ãã¨ã®CDKã¢ããªã±ã¼ã·ã§ã³ã®ãããã¤å 容åãåãã«ã¤ãã¦ãStageã¯ã©ã¹ã®æ´»ç¨ä¾ãç´¹ä»ãã¦ã¿ã¾ããã å ¬å¼ããã¥ã¡ã³ãã§ã®å®è£ ä¾ãè¬ã«Pipelinesã®Stageè¼ã£ã¦ããã¨æ å ±ä¸è¶³æãå¦ããªãã®ã§ããã²çããã®ç´ æµãªä½¿ãæ¹ãã³ã¡ã³ãããã ããã¨å¬ããã§ãã
ãã£ã¨ããéã«å¹´æ«ã§ããï¼ãã®è¨äºãèªãã§é ããæ¹ããæ¥å¹´ãç´ æµãªä¸å¹´ãéããããã¨ãé¡ã£ã¦ãã¾ãã ã¡ãªã¼ã¯ãªã¹ãã¹ï¼