【AWS】AWS CDK version 2(Python)でインフラ環境を構築する手順

AWS Cloud Development Kit(AWS CDK)でインフラ環境を構築する手順について解説します。

現在クラウド環境が主流となってきているなかで、インフラ環境をコード化(Infrastructure as Code(IaC))して管理するケースが多くなっています。

AWS の場合は CloudFormation がありますが、記述形式は JSON か Yaml になります。

AWS CDK でも CloudFormation と同じようにインフラをコード化できますが、AWS CDK はプログラム言語が利用できます。

AWS CDK で利用できるプログラム言語は以下となります。

  • TypeScript
  • JavaScript
  • Python
  • Java
  • C#

今回は Python で実施します。

 

また、AWS CDK はバージョン2がリリースされています。

今回は最新の AWS CDK バージョン2で実施します。

 

環境構築

以下は、AWS CDK Intro Workshopの日本語バージョンです。

 

AWS CDK Intro Workshop

https://catalog.us-east-1.prod.workshops.aws/workshops/99731164-1d19-4d2e-9319-727a130e2d57/ja-JP

 

AWS CDK は日本語の情報が少ない中で上記日本語でのワークショップのサイトは結構貴重です。

 

今回試した環境

  • 自PC ← ノートパソコン
  • OS ← Windows10
  • Python ← Python 3.10.4

Linuxマシンで実施しようと思いましたが、わざわざ AWS CDK を利用するために EC2 インスタンスを立てるのも面倒に思ったのと、コスト面と Windows PC でも AWS CDK が使えるので自PC(Windows10)で作業することにしました。

 

 

AWS CDK 用の IAM ユーザーを作成する

はじめに AWS CDK 用の IAM ユーザーを作成します。

 

IAM ユーザーを作成する際の注意点としては、「AWS 認証情報タイプを選択」で「アクセスキー‐プログラムによるアクセス」にチェックを入れることです。

この IAM ユーザーは AWS CDK 専用とするので「パスワード‐AWS マネジメントコンソールへのアクセス」にはチェックは入れません。

 

 

 

「アクセス許可の設定」「既存のポリシーを直接アタッチ」を選択して「AdministratorAccess」ポリシーにチェックを入れてアタッチします。

 

 

IAM ユーザーを作成したら「アクセスキー」「シークレットアクセスキー」を保存しておきます。

 

 

AWS CLI をインストールする

自PCに AWS CLI をインストールします。

 

【AWS】【Windows&Linux】「EC2 インスタンス」または「パソコン」に AWS CLI(aws コマンド)及び jq コマンドをインストールする手順

 

 

AWS CLI をインストールしたら「aws configure」コマンドを実行して「アクセスキー」「シークレットアクセスキー」を設定します。

 

 

Node.jsのインストール

Node.jsをインストールします。

Windowsの場合は以下のURLにアクセスをして Windows 用のインストーラをダウンロードします。

https://nodejs.org/en/download/current/

 

「Windows Installer」をクリックしてセットアップファイルをダウンロードします。

 

※Node.jsは最新のバージョンを選択した方がいいです。古いバージョンのNode.jsを選択してインストールしてみましたが不明なエラーが出たりして無駄にエラー対応が必要なったので最新のバージョンをインストールすることをお勧めします。

 

ダウンロードしたファイルをダブルクリックして Node.js をインストールします。

 

■バージョン確認

c:\>node –version
v17.8.0

 

c:\>

 

 

Pythonのインストール

今回は AWS CDK with Python で試しますので Python をインストールします。

Pythonのバージョンは 3.6 以上です。

単純に最新バージョンの Python をインストールします。

 

Python の仮想環境を利用するべきか?

Pythonの仮想環境(venv)を利用するべきでしょうか?

今回は自PC で Windows なのでわざわざ仮想環境を利用する必要はないと思い、利用しませんでした。

仮想環境のメリットとしては、Python のバージョンを切り替えられるということが挙げられますが、特に切り替える必要がなければ利用しなくてもいいです。

 

ちなみに AWS CDK は仮想環境(venv)を利用しなくても動きます。

むしろ仮想環境を利用するとところどころエラーが出たりしてエラー対応が面倒です。

 

pipのインストール

pipがインストールされていない場合は pip コマンドもインストールします。

 

以下より get-pip.py ファイルをダウンロードします。

https://bootstrap.pypa.io/get-pip.py

 

python コマンドで get-pip.py を実行します。

■pipのインストール

>python get-pip.py

 

 

■pipのバージョン確認

C:\work\aws-cdk>pip –version 
pip 22.0.4 from C:\Users\xxxxx\AppData\Local\Programs\Python\Python310\lib\site-packages\pip (python 3.10) 

 

 

AWS CDKツールキット

AWS CDK ツールキットをインストールします。

CDK ツールキットをインストールすると cdk コマンドが使えるようになります。

 

■CDK ツールキット(aws-cdk)のインストール

>npm install -g aws-cdk

 

 

■CDK ツールキット(aws-cdk)のバージョン確認

>cdk –version
2.18.0 (build 75c90fa)

 

最初の CDK プロジェクトの作成

環境ができたら最初の CDK プロジェクトを作成します。

 

空のディレクトリを作成します。

c:\work>mkdir aws-cdk

 

 

対象フォルダに移動します。

c:\work>cd aws-cdk

 

新しい Python 用の CDK プロジェクトを作成します。

■CDK プロジェクトの作成

c:\work\aws-cdk>cdk init sample-app –language python

 

■cdk init コマンドの確認

cdk init コマンドだけ実行してオプションを確認します。気が付かないうちに対象のプログラム言語が増えていっています。

C:\work\aws-cdk>cdk init 
Available templates: 
* app: Template for a CDK Application 
   └─ cdk init app –language=[csharp|fsharp|go|java|javascript|python|typescript]  ← このプログラム言語が利用できます。
* lib: Template for a CDK Construct Library 
   └─ cdk init lib –language=typescript 
* sample-app: Example CDK Application with some constructs 
   └─ cdk init sample-app –language=[csharp|fsharp|go|java|javascript|python|typescript]  ← このプログラム言語が利用できます。

 

 

CDK プロジェクトを作成するとサンプルプロジェクトのファイル一式が作成されます。

 

 

CDK でデプロイして環境を構築する

コマンドラインで基本のテンプレートを利用して環境を構築します。

 

■requirements.txtの内容をインストールする

c:\work\aws-cdk>pip install -r requirements.txt

 

 

■CDKアプリが定義した内容をCloudFormationのテンプレートとして出力する

c:\work\aws-cdk>cdk synth

 

 

■CDKToolkitなどの必要なリソース一式を作成する

c:\work\aws-cdk>cdk bootstrap

cdk bootstrap コマンドを実行すると CDKToolkit という CDK を使用するために必要なリソース一式を含む、CloudFormation スタックが作成されます。

 

https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/bootstrapping.html

Deploying AWS CDK apps into an AWS environment (a combination of an AWS account and region) may require that you provision resources the AWS CDK needs to perform the deployment.

AWS CDKアプリをAWS環境(AWSアカウントとリージョンの組み合わせ)にデプロイするには、AWS CDKがデプロイを実行するために必要なリソースをプロビジョニングする必要がある場合があります。

These resources include an Amazon S3 bucket for storing files and IAM roles that grant permissions needed to perform deployments.

これらのリソースには、ファイルを保存するためのAmazon S3バケットと、デプロイの実行に必要なアクセス許可を付与するIAMロールが含まれます。

The process of provisioning these initial resources is called bootstrapping.

これらの初期リソースをプロビジョニングするプロセスは、ブートストラップと呼ばれます。

 

CDKToolkitについて

cdk bootstrap コマンドによって作成されるスタック CDKToolKit はそのアカウントで共通のものであり、そのアカウントで以前に cdk bootstrap が実行されて CDKToolKit スタックが作成されていれば、それ以後は cdk bootstrap を実行する必要はありません。

また、cdk bootstrap を実行済みの状態で cdk bootstrap を実行いただいても CDKToolKit の更新が行われるのみでエラーとはなりません。

 

 

 

■CDKアプリをデプロイする

c:\work\aws-cdk>cdk deploy

 

■確認をスキップしたい場合

c:\work\aws-cdk>cdk deploy –require-approval never

 

cdk deployコマンドを実行すると途中で確認のプロンプトで一旦止まります。そのままコマンドを最後まで実行したい場合は「–require-approval never」オプションを追加します。

 

AWS 公式のサンプルテンプレート

AWS 公式のサンプルテンプレートが github にあります。

 

aws-cdk-examples

https://github.com/aws-samples/aws-cdk-examples

 

テンプレートの書き方に迷ったら参考にできます。

APIリファレンスもありますがサンプルが少ないので、「aws-cdk-examples」が非常に役に立ちます。

そのままコピれば環境が構築できるようになっているので便利です。

 

 

EC2 インスタンスを構築する

「aws-cdk-examples」を参考に EC2 インスタンスを起動してみます。

 

aws-cdk-examples

https://github.com/aws-samples/aws-cdk-examples

 

 

 

aws-cdk-examples/python/ec2/instanceディレクトリに移動すると下図のようにファイル一式があるのでこれを空のフォルダにコピーします。

 

 

 

ファイル一式をコピーしたら app.py ファイルを編集して EC2 インスタンスを定義します。

 

 

■カスタマイズしたapp.pyファイル

import os.path 
 
from aws_cdk.aws_s3_assets import Asset 
 
from aws_cdk import ( 
    aws_ec2 as ec2, 
    aws_iam as iam, 
    App, Stack 

 
from constructs import Construct 
 
dirname = os.path.dirname(__file__) 
 
 
class EC2InstanceStack(Stack): 
 
    def __init__(self, scope: Construct, id: str, **kwargs) -> None: 
        super().__init__(scope, id, **kwargs) 
 
        # VPC 
        vpc = ec2.Vpc(self, “VPC”, 
            cidr=”10.0.0.0/16″, 
            nat_gateways=1, 
            vpc_name=”AWS-CDK-VPC”, 
            enable_dns_hostnames=True, 
            enable_dns_support=True, 
            # max_azs=2とすることでec2.SubnetConfigurationで定義するサブネットが

            # 2つのアベイラビリティゾーンで作成される。 
            # このテンプレートの例ではパブリックサブネットが2つ、プライベートサブネットが2つ、

            # 合計4つのサブネットが作成される。 
            max_azs=2, 
            subnet_configuration=[ 
                ec2.SubnetConfiguration 
                    (name=”public-subnet”,cidr_mask=24,subnet_type=ec2.SubnetType.PUBLIC), 
                ec2.SubnetConfiguration 
                    (name=”private-subnet”,cidr_mask=24,subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT), 
                    ] 
            ) 
         
        # セキュリティグループの定義 
        security_group = ec2.SecurityGroup( 
            self, 
            id=”SecurityGroup”, 
            vpc = vpc, 
            security_group_name=”security-group-test”,             
            description=”SecurityGroupTest”,             
        ) 
         
        # インバウンドの設定を追加する。 

        # ちなみに下でSSMのポリシーを設定しているので22番ポートを開ける必要はないが

        # セキュリティグループのテストで開けている。
        security_group.add_ingress_rule( 

            # ソースIPを設定する。
            peer=ec2.Peer.ipv4(“x.x.x.x/32“), 
            connection=ec2.Port.tcp(22), 
            description=”Allow ssh from Internet” 
        ) 
 
        # AMI の設定
        # 常に最新の AMI が指定されるので便利。
        amzn_linux = ec2.MachineImage.latest_amazon_linux( 
            generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2, 
            edition=ec2.AmazonLinuxEdition.STANDARD, 
            virtualization=ec2.AmazonLinuxVirt.HVM, 
            storage=ec2.AmazonLinuxStorage.GENERAL_PURPOSE 
            ) 
 
        # Instance Role and SSM Managed Policy 
        role = iam.Role(self, “InstanceSSM”, assumed_by=iam.ServicePrincipal(“ec2.amazonaws.com”)) 
 
        role.add_managed_policy(iam.ManagedPolicy.from_aws_managed_policy_name(“AmazonSSMManagedInstanceCore”)) 
 
        # Instance 
        instance = ec2.Instance(self,  
            id=”test-ec2-instance”, 
            instance_name=”aws-cdk-test-instance”, 
            instance_type=ec2.InstanceType(“t3.nano”), 
            # 鍵の設定
            key_name=”my-key”, 
            machine_image=amzn_linux, 
            vpc = vpc, 
            role = role, 
            security_group=security_group, 

            # EC2インスタンスがどこに配置されるのかを決めている。

            # ここではパブリックサブネットに配置するよう指定している。
            vpc_subnets=ec2.SubnetSelection( 
                subnet_type=ec2.SubnetType.PUBLIC 
            ), 
        ) 
 
        # Script in S3 as Asset 
        asset = Asset(self, “Asset”, path=os.path.join(dirname, “configure.sh”)) 
        local_path = instance.user_data.add_s3_download_command( 
            bucket=asset.bucket, 
            bucket_key=asset.s3_object_key 
        ) 
 
        # Userdata executes script from S3 
        instance.user_data.add_execute_file_command( 
            file_path=local_path 
            ) 
        asset.grant_read(instance.role) 
 
app = App() 
EC2InstanceStack(app, “ec2-instance”) 
 
app.synth() 

 

 

■id

id – An identifier that must be unique within this scope.

The identifier serves as a namespace for everything that’s defined within the current construct and is used to allocate unique identities such as resource names and AWS CloudFormation logical IDs.

id –このスコープ内で一意である必要がある識別子です。

識別子は、現在のコンストラクト内で定義されているすべての名前空間として機能し、リソース名や AWS CloudFormation 論理IDなどの一意のIDを割り当てるために使用されます。

 

 

subnet_configuration

subnet_configuration (Optional[Sequence[SubnetConfiguration]]) –

Configure the subnets to build for each AZ.

AZごとに構築するサブネットを構成します。

→subnet_configuration は、アベイラビリティーゾーン (AZ) それぞれ (“each AZ”) に配置するサブネットの設定を記述するパラメータです。上記のコードではそれぞれの AZ に 2 つのサブネットが作成されることになります。

→AZ はリージョンによって個数が異なり、アカウントとリージョンを指定しない場合には、AZ の数は 2 とみなされます。

Each entry in this list configures a Subnet Group; each group will contain a subnet for each Availability Zone.

このリストの各エントリは、サブネットグループを構成します。 各グループには、各アベイラビリティーゾーンのサブネットが含まれます。

For example, if you want 1 public subnet, 1 private subnet, and 1 isolated subnet in each AZ provide the following:: new ec2.Vpc(this, ‘VPC’, { subnetConfiguration: [ { cidrMask: 24, name: ‘ingress’, subnetType: ec2.SubnetType.PUBLIC, }, { cidrMask: 24, name: ‘application’, subnetType: ec2.SubnetType.PRIVATE_WITH_NAT, }, { cidrMask: 28, name: ‘rds’, subnetType: ec2.SubnetType.PRIVATE_ISOLATED, } ] });

Default: – The VPC CIDR will be evenly divided between 1 public and 1 private subnet per AZ.

デフォルト:- VPC CIDR は、AZごとに1つのパブリックサブネットと1つのプライベートサブネットに均等に分割されます。

 

 

■max_azs

max_azs (Union[int, float, None) –

Define the maximum number of AZs to use in this region.

この領域で使用するAZの最大数を定義します。

If the region has more AZs than you want to use (for example, because of EIP limits), pick a lower number here.

リージョンに使用したいよりも多くのAZがある場合(たとえば、EIP制限のため)、ここで小さい数を選択します。

The AZs will be sorted and picked from the start of the list.

AZは、リストの先頭からソートおよび選択されます。

If you pick a higher number than the number of AZs in the region, all AZs in the region will be selected.

リージョン内のAZの数よりも多い数を選択すると、リージョン内のすべてのAZが選択されます。

To use “all AZs” available to your account, use a high number (such as 99).

アカウントで使用可能な「すべてのAZ」を使用するには、高い数値(99など)を使用します。

Be aware that environment-agnostic stacks will be created with access to only 2 AZs, so to use more than 2 AZs, be sure to specify the account and region on your stack.

環境に依存しないスタックは2つのAZにのみアクセスできるように作成されることに注意してください。したがって、2つ以上のAZを使用するには、スタック上のアカウントとリージョンを必ず指定してください。

Default: 3

 

 

上記テンプレートを実行した結果

上記テンプレートを実行した結果、以下のようになります。

 

 

■ブートストラップする

C:\work\aws-cdk>cdk bootstrap  
 ⏳  Bootstrapping environment aws://xxxxxxxxxx/ap-northeast-1… 
Trusted accounts for deployment: (none) 
Trusted accounts for lookup: (none) 
Using default execution policy of ‘arn:aws:iam::aws:policy/AdministratorAccess’. Pass ‘–cloudformation-execution-policies’ to customize.     
CDKToolkit: creating CloudFormation changeset… 
CDKToolkit |  0/12 | 10:46:09 | REVIEW_IN_PROGRESS   | AWS::CloudFormation::Stack | CDKToolkit User Initiated 
CDKToolkit |  0/12 | 10:46:15 | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack | CDKToolkit User Initiated 
CDKToolkit |  0/12 | 10:46:21 | CREATE_IN_PROGRESS   | AWS::IAM::Role        | CloudFormationExecutionRole  
CDKToolkit |  0/12 | 10:46:21 | CREATE_IN_PROGRESS   | AWS::ECR::Repository  | ContainerAssetsRepository  
CDKToolkit |  0/12 | 10:46:21 | CREATE_IN_PROGRESS   | AWS::IAM::Role        | ImagePublishingRole 
CDKToolkit |  0/12 | 10:46:21 | CREATE_IN_PROGRESS   | AWS::S3::Bucket       | StagingBucket 
CDKToolkit |  0/12 | 10:46:21 | CREATE_IN_PROGRESS   | AWS::SSM::Parameter   | CdkBootstrapVersion 
CDKToolkit |  0/12 | 10:46:21 | CREATE_IN_PROGRESS   | AWS::IAM::Role        | LookupRole 
CDKToolkit |  0/12 | 10:46:21 | CREATE_IN_PROGRESS   | AWS::IAM::Role        | FilePublishingRole 

 

~ 省略 ~

CDKToolkit |  8/12 | 10:46:49 | CREATE_COMPLETE      | AWS::S3::BucketPolicy | StagingBucketPolicy 
CDKToolkit |  8/12 | 10:46:49 | CREATE_IN_PROGRESS   | AWS::IAM::Role        | DeploymentActionRole Resource creation Initiated 
CDKToolkit |  8/12 | 10:46:50 | CREATE_IN_PROGRESS   | AWS::IAM::Policy      | FilePublishingRoleDefaultPolicy Resource creation Initiated    
CDKToolkit |  8/12 | 10:46:50 | CREATE_IN_PROGRESS   | AWS::IAM::Policy      | ImagePublishingRoleDefaultPolicy Resource creation Initiated   
CDKToolkit |  9/12 | 10:47:11 | CREATE_COMPLETE      | AWS::IAM::Policy      | FilePublishingRoleDefaultPolicy  
CDKToolkit | 10/12 | 10:47:12 | CREATE_COMPLETE      | AWS::IAM::Policy      | ImagePublishingRoleDefaultPolicy  
CDKToolkit | 11/12 | 10:47:12 | CREATE_COMPLETE      | AWS::IAM::Role        | DeploymentActionRole  
CDKToolkit | 12/12 | 10:47:15 | CREATE_COMPLETE      | AWS::CloudFormation::Stack | CDKToolkit  
 ✅  Environment aws://xxxxxxxxx/ap-northeast-1 bootstrapped. 

 

 

■デプロイする

C:\work\aws-cdk>cdk deploy –require-approval never 
 
✨  Synthesis time: 55.63s 
 
ec2-instance: deploying… 
[0%] start: Publishing a59c8db9c3816b3f:current_account-current_region 
[0%] start: Publishing ad34b6cb129cfebe:current_account-current_region 
[50%] success: Published 34b6cb129cfebe:current_account-current_region 
[100%] success: Published x8db9c3816b3f:current_account-current_region 
ec2-instance: creating CloudFormation changeset… 
ec2-instance |  0/28 | 10:56:36 | REVIEW_IN_PROGRESS   | AWS::CloudFormation::Stack            | ec2-instance User Initiated 
ec2-instance |  0/28 | 10:56:47 | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack            | ec2-instance User Initiated 
ec2-instance |  0/28 | 10:56:52 | CREATE_IN_PROGRESS   | AWS::EC2::EIP                         | VPC/public-subnetSubnet1/EIP (VPCpublicsubnetSubnet1EIP1292D74F) 
ec2-instance |  0/28 | 10:56:52 | CREATE_IN_PROGRESS   | AWS::EC2::InternetGateway             | VPC/IGW (VPCIGWB7E252D3)  
ec2-instance |  0/28 | 10:56:52 | CREATE_IN_PROGRESS   | AWS::CDK::Metadata                    | CDKMetadata/Default (CDKMetadata) 
ec2-instance |  0/28 | 10:56:52 | CREATE_IN_PROGRESS   | AWS::IAM::Role                        | InstanceSSM (InstanceSSMCBFA3CF0) 

 

~ 省略 ~

 
 ✅  ec2-instance 
 
✨  Deployment time: 193.56s 
 
Stack ARN: 
arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxx:stack/ec2-instance/0-b15e-11ec-6638d27df1 
 
✨  Total time: 249.19s 
 
 
 
C:\work\aws-cdk>

 

 

スタックが2つ作成されます。

  • ec2-instance
  • CDKToolkit

■作成されたスタック

 

■作成されたVPC

 

 

■作成されたサブネット

プライベートとパブリックがそれぞれ2つずつ作成されます。

アベイラビリティゾーンは、a と c それぞれ割り振られます。

 

 

■S3バケット

 

 

 

デプロイした CDK アプリの削除

デプロイした CDK アプリはリソースによっては料金がかかります。

その為使い終わった後は削除しましょう。

 

■デプロイしたCDKアプリの削除

c:\work\aws-cdk>cdk destroy

 

■確認をスキップしたい場合

c:\work\aws-cdk>cdk destroy –force

 

削除する場合の注意点

cdk bootstrap コマンドにより CDKToolkit という CDK を使用するために必要なリソース一式を含む CloudFormation スタックが作成されます。

このスタックには CDK の使用過程で必要な S3 バケットも含まれます。

この自動で作成されるバケットには DeletionPolicy 属性が Retain に設定されているため、CDKToolkit を削除しても削除されません。

 

そのため cdk destroy コマンドで CDK アプリを削除して CDKToolkit も削除した場合は、また cdk bootstrap コマンドを実行する必要があり、且つ、S3 バケットが残っていると「cdk-hnxxxxds-assets-xxxxxxxxx-ap-northeast-1 already exists」のエラーが出力されます。

その場合は手動にて S3 バケットを削除した後に cdk bootstrap コマンドを実行します。

 

 

 

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

AlphaOmega Captcha Medica  –  What Do You See?
     
 

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください