CDK(Python)を使ってEC2インスタンスを構築する

最近CDKにハマっています、システムアーキテクト部 サーバレス開発課 石黒です。
CDKで簡単にECインスタンスを作成するデモを紹介したいと思います。

簡単な流れとしては
プロジェクト作成→必要なライブラリインストール→コード書く→デプロイになります。
それではやって行きましょう。

ディレクトリを作成してPythonで開発用に空のプロジェクトを作成します
最近古いCDKのバージョンを使っていると、新しいバージョンがありますとメッセージが出るようになりました。
1.10以前のバージョンだとデプロイ時にエラーになります。

$ mkdir test-cdk-project  && cd test-cdk-project
$ cdk init --language python
Applying project template app for python
Initializing a new git repository...
Executing Creating virtualenv...

# Welcome to your CDK Python project!

This is a blank project for Python development with CDK.

The `cdk.json` file tells the CDK Toolkit how to execute your app.
...
**************************************************
*** Newer version of CDK is available [1.10.1] ***
*** Upgrade recommended                        ***
**************************************************

プロジェクトの構造は主にこんな感じになっています(一部省略)
主に触るのはapp.py、setup.py、test_cdk_project_stack.pyの3つだけです

.
├── .env
|   └──...
├── README.md
├── app.py
├── cdk.json
├── requirements.txt
├── setup.py
└── test_cdk_project
    ├── __init__.py
    └── test_cdk_project_stack.py

仮想環境を有効化

$ source .env/bin/activate

今回EC2を作成するのに必要なライブラリをsetup.pyに追記

...
install_requires=[
        "aws-cdk.core",
        "aws_cdk.aws_ec2",
],
...

pipをアップデートして、ライブラリをインストール

$ pip install --upgrade pip && pip install -r requirements.txt

app.pyにスタックをどこのリージョンにデプロイするかを定義しておきます。

#!/usr/bin/env python3

from aws_cdk import core

from test_cdk_project.test_cdk_project_stack import TestCdkProjectStack


app = core.App()
TestCdkProjectStack(app, "test-cdk-project", env={'region': 'ap-north-east-01'})

app.synth()

次にtest_cdk_project_stack.pyファイルを編集していきます。
ここでEC2を作成するスタックを構成します。
VPC、SecurityGroupも作成させています。

from aws_cdk import (
    aws_ec2,
    core,
)


class TestCdkProjectStack(core.Stack):

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

        cidr = '10.0.0.0/16'

        vpc = aws_ec2.Vpc(
            self,
            id='test-vpc',
            cidr=cidr,
            nat_gateways=1,
            subnet_configuration=[
                aws_ec2.SubnetConfiguration(
                    cidr_mask=18,
                    name='public',
                    subnet_type=aws_ec2.SubnetType.PUBLIC,
                ),
                aws_ec2.SubnetConfiguration(
                    cidr_mask=18,
                    name='private',
                    subnet_type=aws_ec2.SubnetType.PRIVATE,
                ),
            ],
        )

        security_group = aws_ec2.SecurityGroup(
            self,
            id='test-security-group',
            vpc=vpc,
            security_group_name='test-security-group'
        )

        security_group.add_ingress_rule(
            peer=aws_ec2.Peer.ipv4(cidr),
            connection=aws_ec2.Port.tcp(22),
        )

        image_id = aws_ec2.AmazonLinuxImage(generation=aws_ec2.AmazonLinuxGeneration.AMAZON_LINUX_2).get_image(self).image_id

        aws_ec2.CfnInstance(
            self,
            id='test-instance',
            availability_zone="ap-northeast-1a",
            image_id=image_id,
            instance_type="t2.micro",
            key_name='test-ssh-key',
            security_group_ids=[security_group.security_group_id],
            subnet_id=vpc.private_subnets[0].subnet_id,
            tags=[{
                "key": "Name",
                "value": "test-instance"
            }]
        )

ここからは作成したスタックをデプロイして流れになります。

まずはCDKのツールキットスタックをデプロイします。
これは初めてそのリージョンにデプロイする時1回だけで大丈夫です。

$ cdk bootstrap 

次にこのコマンドを試してください。
スタックのCFnテンプレートが標準出力されます。

$ cdk synth
Resources:
  testvpc8985080E:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
...

この時、cdk.outというディレクトリが生成され、その中のtest-cdk-project.template.jsonにも出力されています。デプロイ前の構成確認用途です

.
├── app.py
├── cdk.json
├── cdk.out
│   ├── cdk.out
│   ├── manifest.json
│   ├── test-cdk-project.template.json
│   └── tree.json

デプロイ可能なスタックを一覧表示して、指定のスタックをデプロイ開始です。

$ cdk ls
test-cdk-project
$ cdk deploy test-cdk-project
test-cdk-project: deploying...
test-cdk-project: creating CloudFormation changeset...

デプロイが完了したらコンソールで確認してみましょう
CloudFormationのスタックにデプロイしたスタックが表示されています

作成したインスタンスもきちんと作られていますね
お疲れ様でした。

まとめ

CDKを使うと簡単にAWSの環境を構築できてしまいます。
まさにInfrastructure as Codeですね。
cdk docsコマンドでAPIのリファレンスのリンクに飛ぶので
色々な構成でぜひ試してみてください。
ちなみにAPIの接頭にCfnと名のつくものがあります。
これは高レベルAPIか低レベルAPIかの違いです。
高レベルAPIの方がオブジェクト指向なプログラムを書くことができるので
基本高レベルAPIを使用する方が良いかと思います。
ただ高レベルAPIだと提供されていない機能(RDSのセキュリティグループ指定など)があるので、
自分が設定したい属性がない場合には、接頭にCfnがつく低レベルAPIを探すと良いかと思います。

CDKはAWSのリソースをコードで書いて設定するわけなので、AWSのサービスに対する知識が養われます。
最近SAAを取得したのですが、CDKで書いたことが深い理解に役に立った気がしています。
CDK最高…!!!

投稿者プロフィール

ishiguro
新卒1年目です。
暇なときにはARアプリやLINEBotなどで遊んでいます。

ABOUTこの記事をかいた人

新卒1年目です。 暇なときにはARアプリやLINEBotなどで遊んでいます。