Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CDKを使って爆速でナレッジサイトを公開した話

 CDKを使って爆速でナレッジサイトを公開した話

nyankotaro

May 20, 2023
Tweet

More Decks by nyankotaro

Other Decks in Technology

Transcript

  1. CDKを使って爆速でナレッジサイトを公開した話
    2023.05.20
    クラスメソッド株式会社 高山晃太朗
    1
    CDK Conference Japan 2023

    View Slide

  2. 2
    自己紹介
    高山晃太朗(@nyan_kotaroo)
    所属 : AWS事業本部コンサルティング
    趣味 : ねこ、筋トレ
    経歴 : 金融系インフラSE4年 -> クラスメソッド
    ロール : 技術コンサル、ナレッジサイトの運用

    View Slide

  3. 3
    ナレッジサイト is
    Classmethod Cloud Guidebook
    (通称CCG)

    View Slide

  4. AWS利用ガイドライン 4

    View Slide

  5. 5
    AWS Security Hubガイド

    View Slide

  6. 6
    CCGを見るには
    クラスメソッドメンバーズのお客様は無料で見れます!
    デモサイトも公開中 ↓
    https://demo.guidebook.classmethod.net/

    View Slide

  7. 7
    CDKを使って爆速でCCGを公開した話

    View Slide

  8. 8
    なぜCCG公開するのか
    もとはドキュメントで公開してたが、
    参照性を良くしたかった
    より多くの人に公開したかった

    View Slide

  9. 9
    CDKを採用した理由
    Constructでさくっと実装したかった

    View Slide

  10. 10
    Construct
    L1 Construct : “CFn”で始まるCloudFormationに
    対応するライブラリ
    L2 Construct : 複数のリソースからなる抽象化された
    ライブラリ(メインで使う)
    L3 Construct : 特定のユースケースのパターンが記載された
    ハイレベルで抽象化されたライブラリ

    View Slide

  11. 11
    L2が対応してないパラメータがあったとき
    L2 Constructが用意されていればL2で問題なし!
    L2で触れないパラメータはあとからL1で上書き可能
    const bucket = new s3.Bucket(this, 'Bucket', {
    blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
    bucketKeyEnabled: true,
    ...
    });
    // L1コンストラクトでAWS::S3::Bucket ReplicationConfigurationを設定する
    const cfnBucket = bucket.node.defaultChild as s3.CfnBucket;
    cfnBucket.addOverride('Properties.ReplicationConfiguration', {
    Role: replicationRole.roleArn,
    Rules: [
    {
    DeleteMarkerReplication: {
    Status: 'Disabled',
    },
    Destination: {
    AccessControlTranslation: {
    Owner: 'Destination',
    },
    ...
    },
    },
    ],
    });

    View Slide

  12. 12
    実装したもの
    MkDocs

    View Slide

  13. 13
    大人の事情により...
    認証の実装が発生

    View Slide

  14. 14
    最終的に実装したもの
    認証の実装
    MkDocs

    View Slide

  15. 15
    最終的に実装したもの
    https://dev.classmethod.jp/articles/aws-cdk-multi-environment-config/
    CloudFrontの署名付きCookieで認証

    View Slide

  16. 16
    突然のコード開発

    View Slide

  17. 17
    だいじょうぶ。そう、CDKならね

    View Slide

  18. 18
    コード開発爆上がりポイント
    Construct
    ホットスワップ機能(--hotswap)
    NodejsFunction
    BucketDeployment

    View Slide

  19. 19
    Construct
    JavaScript/TypeScriptの自動コンパイルを行い
    esbuildによるLambda関数のアセットをバンドルしてくれる
    NodejsFunction
    BucketDeployment
    TypeScriptでCDKを使っていればpackage.jsonをlambdaと共有可
    ローカルファイルをS3にアップロードしてくれる
    オプションでCloudFrontキャッシュ削除も可能
    Lambda開発で利用
    ログインページのホスティングで利用
    Experimental(試験的)にはなりますが、pythonとgoも拡張されたConstructがあります。

    View Slide

  20. 20
    ホットスワップ機能(--hotswap)
    CloudFormationを変更せず、リソースを直接更新するオプション
    対応リソース
    Lambda コード/タグ/説明/環境変数/バージョン/エイリアス
    Step Functions ステートマシン定義
    ECS コンテナアセット
    S3 静的ホスティングリソース
    CodeBuild プロジェクト/ソース
    AppSync VTLマッピングテンプレート
    ※本番環境での利用は非推奨

    View Slide

  21. 21
    ホットスワップ機能(--hotswap)
    CloudFormationを変更せず、リソースを直接更新するオプション
    対応リソース
    Lambda コード/タグ/説明/環境変数/バージョン/エイリアス
    Step Functions ステートマシン定義
    ECS コンテナアセット
    S3 静的ホスティングリソース
    CodeBuild プロジェクト/ソース
    AppSync VTLマッピングテンプレート
    cdk deploy
    cdk deploy --hotswap
    ※本番環境での利用は非推奨
    約50秒削減

    View Slide

  22. 22
    ここでもう一つ
    デモサイトも用意したいな

    View Slide

  23. 23
    contextによる環境分離

    View Slide

  24. 24
    contextによる環境分離
    {
    "app": "npx ts-node --prefer-ts-exts bin/test.ts",
    ...
    "context": {
    "projectName": "testproject",
    "dev": {
    "accountId": "111122223333",
    "envName": "dev",
    "region": "ap-northeast-1"
    },
    "stg": {
    "accountId": "111122223333",
    "envName": "dev",
    "region": "ap-northeast-1"
    },
    "prd": {
    "accountId": "444455556666",
    "envName": "prd",
    "region": "ap-northeast-1"
    },
    ...
    }
    }
    cdk.json
    const app = new cdk.App();
    const projectName = app.node.tryGetContext('projectName');
    const envKey = app.node.tryGetContext('env');
    const envValues = app.node.tryGetContext(envKey);
    const env = {
    account: envValues.accountId,
    region: envValues.region,
    };
    new TestStack(app, `${projectName}-${envValues.envName}-stack`, {
    projectName: projectName,
    envName: envValues.envName,
    env,
    });
    bin/test.ts
    export interface props extends cdk.StackProps {
    projectName: string;
    envName: string;
    }
    export class TestStack extends cdk.Stack {
    constructor(scope: Construct, id: string, props: props) {
    super(scope, id, props);
    new ec2.Vpc(this, 'Vpc', {
    vpcName: `${props.projectName}-${props.envName}-vpc`,
    });
    }
    }
    lib/test-stack.ts
    > cdk deploy –c env=dev
    envValuesでdevのオブジェクトを扱える

    View Slide

  25. 25
    contextによる環境分離
    {
    "app": "npx ts-node --prefer-ts-exts bin/test.ts",
    ...
    "context": {
    "projectName": "testproject",
    "dev": {
    "accountId": "111122223333",
    "envName": "dev",
    "region": "ap-northeast-1"
    },
    "stg": {
    "accountId": "111122223333",
    "envName": "dev",
    "region": "ap-northeast-1"
    },
    "prd": {
    "accountId": "444455556666",
    "envName": "prd",
    "region": "ap-northeast-1"
    },
    ...
    }
    }
    cdk.json
    const app = new cdk.App();
    const projectName = app.node.tryGetContext('projectName');
    const envKey = app.node.tryGetContext('env');
    const envValues = app.node.tryGetContext(envKey);
    const env = {
    account: envValues.accountId,
    region: envValues.region,
    };
    new TestStack(app, `${projectName}-${envValues.envName}-stack`, {
    projectName: projectName,
    envName: envValues.envName,
    env,
    });
    bin/test.ts
    export interface props extends cdk.StackProps {
    projectName: string;
    envName: string;
    }
    export class TestStack extends cdk.Stack {
    constructor(scope: Construct, id: string, props: props) {
    super(scope, id, props);
    new ec2.Vpc(this, 'Vpc', {
    vpcName: `${props.projectName}-${props.envName}-vpc`,
    });
    }
    }
    lib/test-stack.ts
    > cdk deploy –c env=dev
    > cdk deploy –c env=stg
    -c env=devのリソース
    -c env=stgのリソース

    View Slide

  26. 26
    contextによる環境分離
    export interface props extends cdk.StackProps {
    projectName: string;
    envName: string;
    }
    export class TestStack extends cdk.Stack {
    constructor(scope: Construct, id: string, props: props) {
    super(scope, id, props);
    if (props.envName === 'demo') {
    new StaticSite(this, 'StaticSite’, {
    projectName: props.projectName,
    envName: props.envName,
    });
    } else {
    const authentication = new Authentication(this, 'Authentication', {
    projectName: props.projectName,
    envName: props.envName,
    });
    new StaticSite(this, 'StaticSite', {
    projectName: props.projectName,
    envName: props.envName,
    authApi: authentication.authApi,
    });
    }
    }
    }
    test-stack.ts
    機能ごとにカスタムconstructを作成し、contextを使った条件分岐でconstructを
    組み変えることで、同一ソース内で環境ごとに構成の違うStackを作成することができる
    demo環境では認証機能はデプロイしないような例

    View Slide

  27. 27
    contextによる環境分離
    https://dev.classmethod.jp/articles/aws-cdk-multi-environment-config/
    型定義をしたい
    環境毎に定義ファイルを分けたい
    外部ファイル(.ts)を利用する
    https://dev.classmethod.jp/articles/typescript_aws_cdk_config_pattern/
    cdk.jsonの他に...

    View Slide

  28. 28
    まとめ
    AWS CDKを使うことでインフラ管理はもちろん
    コード開発部分でも開発者体験の向上を実感することができた
    Contextとプログラミング言語の特性を組み合わせることで
    環境ごとのデプロイが容易

    View Slide

  29. 29
    CCGを見るには
    クラスメソッドメンバーズのお客様は無料で見れます!
    デモサイトも公開中 ↓
    https://demo.guidebook.classmethod.net/

    View Slide

  30. 30

    View Slide