CI/CDはじめの一歩 IaC実践編 - CDKを使ったリソースの構築

    CI/CDはじめの一歩 IaC実践編 - CDKを使ったリソースの構築

    目次

      はじめに

      アジアクエスト クラウドインテグレーション部の田中雄也です。
      この記事では、CI/CDを知るための一歩として、インフラ環境をコード化するIaCを実際に行った手順についてご紹介します。
      この記事を読むことで、インフラ構築の手段として、コードで記述するという手法が存在することを知ることができます。それらの手法の具体的な活用例を知ることで、より効率的な環境構築を意識できるようになっていただけると幸いです。

      また、この記事は以前投稿をした、CI/CDはじめの一歩 IaC編の内容を実際に実践してみる。といった内容の記事になっています。
      そもそもIaCとは?という部分を詳しく知りたい方はこの記事より前に以前の記事に目を通していただくとより理解が深まるかと思います。

      記事の目的(または狙い)

      • 今後、CI/CDやIaCに触れてみたい方のきっかけづくりに
      • IaCの情報収集をする方向けの参考情報に
      • インフラ構築の手段を学べる

      関係リソースの紹介

      今回のIaC実践にあたって、関係してくる要素やリソースについておおまかにご紹介します。

       

      AWS CloudFormation

      AWSのIaCツールで、JSON/YAML形式でAWSリソースを定義・構築するサービスです。
      作成するコードはテンプレートと呼ばれ、これを用いることで同様の構成を何度でも構築できます。
      最小単位は、1つのテンプレートによって作成されたリソース群であり、スタックと呼ばれます。
      また、スタックの集まりであるスタックセットという機能を利用することで、複数のアカウントやリージョンに対して一気に展開することが可能になります。
      基本的にコードの記述をリソースと一対一の関係で行う必要があるため、コードが長くなりやすいです。

      今回の実践では、CDKを用いて合成されたコードを実際にAWS環境にデプロイするため用いられます。

       

      AWS CDK (AWS Cloud Development Kit)

      AWS CDKの働きは、以下の画像のように使い慣れたプログラミング言語を用いて記述したインフラ環境のコードを、CloudFormation(以下CFn)が利活用できる形に合成することにあります。

      202406_first_steps_to_cicd_iac_practice_01

      CDKを利用することによるメリットとしては

      • 使い慣れた言語でインフラ開発ができるため学習コストを抑えられること
      • プログラミング言語由来の複雑な処理ができるため、環境構築におけるコードの記述量を減らすことができること
        • 言語にもよるが、同一の環境を構築する際、CFnでは、500-1000行かかるコードをCDKを用いることで数十行程度に抑えることが可能

      などが挙げられます。

      今回のデモでは、こんなCDKを使ったインフラ構築を実践します。

       

      なぜ、記述量に大きな差がでるのか?

      同一環境を構築する際に、CFnでは500行近く記述をしなければならないコードをCDKでは数十行程度で記述が済んでしまうのはなぜなんでしょうか?
      そこには、CDKにおけるライブラリと呼ばれるテンプレートのようなものが関係しています。

      CDKには、Constructと呼ばれるリソースを定義するライブラリがそれぞれ存在し、以下のようなレベルが存在しています。

      • L3 Patterns
        • 高い抽象度に基づいて一般的なタスクを完了するに足り得る複数の種類のリソースを内包したレベル
      • L2 High level
        • 直感的にリソースを定義できるレベルで、デフォルト値や便利なメソッドが定義済みなため利用しやすい
      • L1 low level
        • CFNと同様のレベルで、各リソースにおけるパラメータを詳細に定義する必要がある
          • 逆にいうと、細かいパラメータを定義したい場合に向いている

      Construct全体では、それぞれL3が40%,L2が50%,L1が10%を占めています。高次のレベルになればなるほど、AWS側で事前に用意されたテンプレートに沿って指定をすることで、詳細な設定まで書き込む必要がないというイメージになっています。

      つまり、CDKにおいてはConstructというライブラリが利用できるため、詳細なパラメータを定義する必要がなく、それがリソースに対して一対一でパラメータを記述する必要のあるとのCFn記述量の差となっているのです。

      実践内容の概要

      というわけで、ここからは実際にCDKを通して、クラウド環境上にリソースのデプロイを行った時の様子をご紹介する前段階として、実際にどういった作業をしたのか。ということについて、概要をご紹介します!

      今回の実践では、先ほどご紹介したCDKを通じて、以下の環境をAWS上にデプロイすることを目指します。

      202406_first_steps_to_cicd_iac_practice_02

      構成として、ユーザから見たアクセス窓口としてALBがあり、その背後のFargateというコンテナに対して負荷分散をしている形となっています。

      今回の実践では、環境構築が完了次第、アクセス窓口となっているALBにDNS名経由でアクセスをし、最終的に末端のFargate上にデプロイされた環境へアクセスができるかどうかといった部分まで試していきたいと考えています。


      また、今回のデモで用いるCDK CLIコマンドについても触れておきます。

       

      コマンド 機能
      cdk init カレントディレクトリにCDKプロジェクトを作成
      cdk bootstrap CDK Toolkitステージングスタックをデプロイ(初回利用時に必要)
      cdk synth スタックのテンプレートを合成して表示
      cdk deploy synthで作成したスタックをデプロイ
      cdk destroy スタックを削除

      今回、CDKを使うために、上記のようなコマンドを使っていきますので、軽く目を通して機能を確認していただければと思います。

       

      事前準備

      実際にここからの手順を試したいという方へ
      今回ご紹介している手順を実行するためには、使用するLinux環境へ以下のものをインストールすることが必要になります。

      • Node.js
      • AWS CLI

      今回は、本筋とは逸れてしまう部分になるため、割愛します。逐次ご自身で確認していただきながら進めてもらうようお願いいたします。

      いざ実践!

      では、実際にここから構築時の様子を紹介します。

       

      cdk initで環境を準備する

      まず行うことはcdk initを実行してCDK用の環境を作成することです。

      さっそく、以下のコマンドを実行します。

      cdk init app --language python

      ※この際、cdk initを実行した時のディレクトリにCDK用のプロジェクトが作成されますので、新規のディレクトリを作成し、その中でコマンド実行することをおすすめします。

      コマンドを実行すると、下の画像のような形で、Python用のCDKのプロジェクトが自動で作成されるので完了のメッセージが表示されるまで少し待ちます。

      202406_first_steps_to_cicd_iac_practice_03

      実行が完了すると、なにもなかった新規のディレクトリのなかにファイルやディレクトリが作成されていることが確認できるはずです。

       

      必要なパッケージのインストールをする

      下記のコマンドを実行し、 CDKに関わるアプリケーションの依存関係周りの情報をインストールします。

      pip install -r requirements.txt

      これも多少時間がかかるので少し待ちます。
      ちなみにこのコマンドは、cdk init実行中のメッセージのなかにも記載があるはずなので、興味があれば確認してみてください。

       

      リソースのデプロイ先を規定する

      忘れないうちにリソースのデプロイ先のリージョン情報を規定します。
      今回は、デフォルトのアカウントとデフォルトのリージョンを使用していきたいので、cdk initで作成した環境のなかにあるapp.pyファイルを編集することで、その旨を指定します。

      202406_first_steps_to_cicd_iac_practice_04

      画像でいうと、18行目の部分(envから始まる行)が元々コメントアウトされているはずなので、先頭の「#」を外して有効化します。

      この操作によって、CDKを使って作られた環境のデプロイ先がAWS CLIで指定をしているデフォルトのAWSアカウントとリージョンになります。(一応、この手順を行わなくても、CLIのデフォルト環境にデプロイされるようですが、念を入れて明示的にするためにアンコメントをする手順を行いました)

       

      CDKのコード内容を記述する

      次に、実際のCDKに用いるコードを記述します。
      この際、CDKのコードが格納されているディレクトリやファイルは、cdk init実行時のディレクトリ名を基にして命名されるため、個々人の環境によって異なった名前となります。
      ちょっとややこしいのですが、私の場合は「CDK_demo」ディレクトリでcdk initを実行したため、CDK_demoフォルダ内のcdk_demoの中にCDKのコードを記述するためのファイル「cdk_demo_stack.py」(人によって名前が異なる)が格納されていました。

      cdk_demo_stack.pyファイルを開くと、すでにコードが記述されていますが、今回は実践内容の概要の部分でお見せした構成を実現するために、下記のようにコードを書き換えていきます。

      from aws_cdk import (
      Stack,
      aws_ec2 as ec2,
      aws_ecs as ecs,
      aws_ecs_patterns as ecs_patterns,
      )
      from constructs import Construct

      class CdkDemoStack(Stack): # 'Class' should be 'class'

      def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
      super().__init__(scope, construct_id, **kwargs)

      vpc = ec2.Vpc(self, "Vpc", max_azs=3)

      cluster = ecs.Cluster(self, "Cluster", vpc=vpc)

      ecs_patterns.ApplicationLoadBalancedFargateService(self, "FargateService",
      cluster=cluster, # Required
      cpu=512, # Default is 256
      desired_count=6, # Default is 1
      task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions( # Corrected argument name
      image=ecs.ContainerImage.from_registry("amazon/amazon-ecs-sample")), # Corrected attribute reference
      memory_limit_mib=2048, # Default is 512
      public_load_balancer=True) # Default is True

      リソース部分に絞ってそれぞれの動きを確認すると以下のようになっています。

      • vpc
        • max_azs=3という引数により、最大3つのアベイラビリティゾーンを跨ぐVPCを作成
      • cluster
        • 上で定義したvpc内にecsのクラスターをデプロイするように記述
      • ecs_patterns.ApplicationLoadBalancedFargateService
        • ECSクラスター上にFargateサービスをデプロイするように記述。この部分で、アプリケーションロードバランサーが関連付けやFargateのスペックの定義等を行っている
          • task_image_optionsでは使用するコンテナイメージを指定しており、このコードでは、"amazon/amazon-ecs-sample"として、AWSが提供のecsのテスト用のimageを指定
          • ※私が用いたイメージとは違うものなので、最終的に出力されるページが異なりますが、その点はあまり気にしなくても大丈夫です

      cdk synthでコードを合成する

      では、ここからCDKの目玉となるコードの合成を行っていきます。

      この際、初回実行であればコード内で用いているライブラリが実行環境にインストールされていないはずなので、先ほどインストールをしたrequirements.txtを確認の上、ライブラリのバージョンを合わせた上で下記のコマンドを実行してライブラリをインストールします。

      pip install aws-cdk-lib==2.110.1 constructs

      ライブラリのインストールまでできたら、以下のコマンドを実行します。

      cdk synth

      cdk synthの実行がうまくいくと、画像のように次々とCFnのコードが合成されていく様が確認できます。

      202406_first_steps_to_cicd_iac_practice_05

      合成したコードを確認してみよう

      合成されたコードは私の場合、cdk.outフォルダ内のCdkDemostack.Template.jsonファイルに格納されていました。
      実際に、cdk synthを使って合成したコードを確認してみると

      202406_first_steps_to_cicd_iac_practice_06

      JSON形式で1100行余にわたってコードが記述されていることが確認できます。
      記述の形式など諸々異なる部分があるため、単純比較できるものではないですが、元々Pythonで記述していた合成前のコードが25行であったことを考えると、その差が約40倍あることを見て取れます。

      今回の環境であってもこれだけの記述量があるという点で、JSONのファイルを自分が手作業で記述することを考えると、大変な苦労があるということをご理解いただけたでしょうか?これが、IaCでの開発においてCDKが選ばれる理由になっているのです。

       

      cdk deployでコードをデプロイする

      コードの合成までの手順が終わりましたので、ここからは実際に作成されたコードをAWSの環境上にデプロイしていきます。

      そのためにまずAWS CLIと実際のAWSアカウントの間で情報のやりとりをするために、クレデンシャルの認証をする必要があります。
      手順としては、画像のようにAWSのログイン画面から「Command line or programmatic access」をクリックし、そこで表示された情報をAWS CLI実行環境へ貼り付けて実行をすることで、認証ができます。

      202406_first_steps_to_cicd_iac_practice_07

      この際、表示されたいくつかのOptionのなかで、Option1の情報をクリックしてコピーし、その情報をAWS CLI環境へ貼り付けするのが一番簡単かなとは思います。

      デプロイ先のAWS環境ではじめてCDKを使う場合

      ※以降の手順を進める前に、初回実行時であったり、デプロイ先においてはじめてCDKを使う場合には事前にcdk bootstrapコマンドでAWSアカウント内にCDKでのデプロイ用の環境を整えておく必要があります。

      202406_first_steps_to_cicd_iac_practice_summary

      cdk bootstrapを実行するかどうかは、AWSアカウントの対象のリージョンにおいてCloudFormationのスタックを確認し、CDKToolKitが存在してるかどうかで判断できます。存在していればbootstrap実行の必要はないですし、存在していなければbootstrapを実行する必要があります。

      その際、CLIツールからAWS環境へアクセスをする必要があるため、先ほどのクレデンシャルの認証を済ませた状態でbootstrapを実行してください。

       

      cdk deployを実行する!

      ここまでの諸々の手順が終わったら、さっそくcdk deployを実行してみましょう。

      cdk deploy

      コマンド自体は単純なもので上記だけとなります。

      少し待つと、画像のようにIAMやsecurity Groupなどについて確認をされるので、「y」を入力し、処理を続行させます。

      202406_first_steps_to_cicd_iac_practice_08

      ちなみに、この状態でAWS CFnをコンソール上から確認しにいくと、リソースが作成途中になっていることが確認できます。

      202406_first_steps_to_cicd_iac_practice_09

      そのまま、少し待ってCFnスタックの作成状況がCOMPLETEになればデプロイは完了です。

      202406_first_steps_to_cicd_iac_practice_10

      次のステップでは、実際にデプロイした環境にアクセスしてみましょう。

       

      デプロイした環境にアクセスする

      ここでは、実際にデプロイされた環境にアクセスをします。
      そのために、今回作成をしたロードバランサーの画面を開き、DNS名をコピーします。

      202406_first_steps_to_cicd_iac_practice_11

      DNS名をコピーしたら、その値をブラウザのアドレスバーに貼り付けます。
      IaCでの構築が上手くいっていれば、コンテナ経由で指定されたimage通りのサイトが表示されるはずです。

      202406_first_steps_to_cicd_iac_practice_12

      今回は、自分で作成したimageを指定していたため、上記のようなサイトが表示されました。

      ここまでで、CDKを通じたIaCでリソースの構築が行えることやその手順について一通り見ていただきました。
      CDKを利用することで、リソース構築をより効率化できますので、今後IaCでのリソース構築の機会があった際にはぜひ、CDKも選択肢に含めていただけるとよいかと思います。

       

      デプロイした環境を削除する

      IaCを通じて実際にデプロイした環境の削除について触れていきます。
      IaCを通して構築した環境は、作成されたリソース数が多く削除をしていくのが億劫だと思われた方もいるんじゃないでしょうか?
      しかし、今回のような場合であれば、CFnから対象のスタックの削除を行うだけで関連する全てのリソースを削除可能ですので、お手軽に環境の削除ができます。

      手順としても

      1. AWS上でCloudFormationの画面を開く
      2. 対象のスタックを選択する
      3. 削除ボタンを押す

      というステップだけでスタックに関わる全てのリソースを削除でき、とても簡単です。

      とはいえ、このステップを忘れてしまうと、知らず知らずのうちにリソースの使用料金が課金され続けてしまうという事態になってしまいますので、「不要になったリソースは最後にはきちんと削除すること」を忘れずに行いましょう!

      まとめ

      というわけで、この記事では「CI/CDはじめの一歩 IaC実践編」として、IaCとCDKについて実践した内容をご紹介させていただきました。

      この記事を通して伝えたかった、CDKの実践的な使い方とその流れをご理解いただけたでしょうか?

      この記事が皆様のCI/CDやIaCに踏み出す一歩として寄与することを願っています。
      最後までお読みいただき、ありがとうございました。

      また、この記事は
      以前に投稿したCI/CDはじめの一歩シリーズの一部となっています。

      以前の記事をご覧になりたい方は下記のリンクより参照できますので、よければご覧ください。

      CI/CDはじめの一歩 ソースコード管理(Git)編

      CI/CDはじめの一歩 CIツール編

      CI/CDはじめの一歩 構成管理ツール編

      CI/CDはじめの一歩 IaC編

      参考記事

      AWS Cloud Development Kit (AWS CDK) v2 | AWS