Primary About Development

[CDK入門]TypescriptでEC2の環境を作る

2020-10-18

CDKを使うことでAWSのリソースをプログラミング言語を使用して定義する事ができます。 コマンド1つでAWSの環境を作成・削除ができるので、とっても便利です。 CDKのコードさえあれば他人が作った環境再現できたり、開発中は値段を抑えるためにこまめにリソースを削除しておくみたいなことができます。

今回はTypescript + CDKを使用して、EC2の環境構築をしてsshでリモートログインするところまでやってみたいと思います。

準備

本記事はAWSアカウントを持っていることとNode.jsがインストールされていることを想定しています。 OSはmacOSを使用しています。

1. AWS CLIのインストール

macOSの場合は次のコマンドでインストールできます。

bash
curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
unzip awscli-bundle.zip
sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws

その他のOSのインストール方法もawsのドキュメントに書いてあります。 AWSのドキュメントは日本語に対応しているので嬉しいですね。

インストールできたかaws --versionコマンドを実行して確認してください。正しくインストールできていればバージョンが表示されるはずです。

2. AWS CLIのセットアップ

awsコマンドが実行できたら、次に以下のコマンドを実行します。

bash
aws configure
AWS Access Key ID [None]: <自分のアクセスキーID>
AWS Secret Access Key [None]: <自分のシークレットキー>
Default region name [None]: ap-northeast-1
Default output format [None]: json

このコマンドを実行するとアクセスキーID、シークレットアクセスキー、AWSリージョン、出力形式の4つが聞かれます。

アクセスキーIDとシークレットアクセスキーは自分のAWSアカウントのコンソールから確認する事ができます。取得方法はドキュメントを確認してください。 AWSリージョンは東京リージョンを使いたいのでap-northeast-1としました。

詳細はドキュメントを確認してください。

3. AWC CDKのインストール

cdkのインストールはnpmで行います。以下のコマンドを実行してください。

bash
npm install -g aws-cdk

cdk --versionコマンドを実行して、バージョンが表示されたら成功です。

最後に認証情報が正しく設定されていることを確認するために、以下のコマンドを実行します。

bash
cdk bootstrap

以上で環境構築は終了です。

CDKを使う

CDKを使う環境ができたので、実際にCDKを使ってEC2を作成していきます。

1. プロジェクトの作成

まずはじめに、CDKのプロジェクトを作成します。 今回はプロジェクト名をhello-cdkにします。 以下のコマンドを実行して、作業用のディレクトリを作成します。

bash
mkdir hello-cdk
cd hello-cdk

次にcdk initコマンドを使用し、アプリを初期化します。

bash
cdk init app --language typescript

このコマンドを実行すると、hello-cdk以下にCDK用のディレクトリが作成されます。

2. リソースを定義する

cdk initを実行すると, hello-cdk/lib/hello-cdk-stack.tsが作成されます。 このファイルにプログラムを書くことでAWSのリソースを定義することができます。

今回はVPCのパブリックサブネットの中にEC2を配置します。

VPCを定義

まずはCDKのEC2用のライブラリをインストールします。以下のコマンドを実行してください。

bash
npm install -D @aws-cdk/aws-ec2

これによりpackage.jsonのdevDependenciesに@aws-cdk/aws-ec2が追加されるはずです。 次にhello-cdk-stack.tsにVPC用ののコードをかきます。

import * as cdk from '@aws-cdk/core';
import { SubnetType, Vpc } from '@aws-cdk/aws-ec2';

export class HelloCdkStack extends cdk.Stack {
  constructor(
    scope: cdk.Construct, 
    id: string, 
    props?: cdk.StackProps) {
    
    super(scope, id, props);

    const vpc = new Vpc(this, "hello-vpc", {
      maxAzs: 1,
      subnetConfiguration: [
        {
          name: 'public',
          subnetType: SubnetType.PUBLIC
        }
      ],
      natGateways: 0
    })
  }
}

Vpcのコンストラクタの第1引数にはthis, 第2引数にはid、第3引数にはプロパティを指定します。

上記のようにsubnetConfigrationプロパティを設定することでパブリックサブネットを作成することができます。 maxAzsプロパティではアベイラビリティゾーン(AZ)の数を設定しています。デフォルトでは異なるAZに複数のパブリックサブネットが作成されてしまうので、1に設定しました。

NATGatewayが作成されないように、natGatewaysに0を指定していることに注意してください。 NatGatewayは作成されると時間単位で課金されてしまします。

このコードを書いたら一旦AWSにデプロイしてみましょう。

bash
cdk deploy

デプロイが完了したらAWSコンソールのVPCを見てみましょう。リソースが作成されていたら成功です。

sshキーを生成する

次にaws-cliコマンドを用いてsshキーを生成します。 キーの名前を指定する必要があるので、今回はHelloKeyとします。

bash
aws ec2 create-key-pair --key-name HelloKey --query 'KeyMaterial' --output text > HelloKey.pem

HelloKey.pemが作成されたら権限を付与します。

bash
chmod 400 HelloKey.pem

詳細はドキュメントに載ってます。

EC2インスタンスを定義

ssh用のキーが作成できたので、EC2インスタンスの定義をhello-cdk-stack.tsに追記していきます。

import * as cdk from '@aws-cdk/core';
import { 
  AmazonLinuxImage, 
  Instance, 
  InstanceClass, 
  InstanceSize, 
  InstanceType, 
  Peer, 
  Port, 
  SecurityGroup, 
  SubnetType, 
  Vpc 
} from '@aws-cdk/aws-ec2';

export class HelloCdkStack extends cdk.Stack {
  constructor(
    scope: cdk.Construct, 
    id: string, 
    props?: cdk.StackProps) {

    super(scope, id, props);

    const vpc = new Vpc(this, "HelloVPC", {
      maxAzs: 1,
      subnetConfiguration: [
        {
          name: 'Public',
          subnetType: SubnetType.PUBLIC
        }
      ],
      natGateways: 0
    })

    const sg = new SecurityGroup(this, 'HelloSG', {
      vpc: vpc,
      securityGroupName: 'HelloSecurityGroup',
      allowAllOutbound: true,
    })

    sg.addIngressRule(
      Peer.anyIpv4(),
      Port.tcp(22),
    )

    const host = new Instance(this, "HelloInstance", {
      vpc: vpc,
      machineImage: new AmazonLinuxImage(),
      instanceType: InstanceType.of(
        InstanceClass.T3, InstanceSize.NANO
      ),
      securityGroup: sg,
      keyName: "HelloKey"
    })
  }
}

まずはセキュリティグループを作成します。作成したセキュリティグループにaddInressRuleでssh用のポート開けます。これがないとsshすることができません。 現在はIPアドレスはPeer.anyIpv4()に設定してあり、どのIPからでもアクセスできます。しかし、可能ならsshは特定のIPからのみアクセスできるようにしたほうがセキュアーだと思います。

EC2はAmazonLinuxのイメージを使用してサイズは一番小さいt3.nanoを使用しました。 EC2インスタンスのkeyNameというプロパティに先程作成したsshキーの名前を設定することで、ssh可能になります。

コードがかけたらデプロイしましょう。

bash
cdk deploy

3. EC2にsshする

デプロイできたらAWSコンソールのEC2を見てみましょう。CDKで作成されたEC2インスタンスがあるはずです。 インスタンスをみつけたら、コンソールにあるEC2インスタンスのパブリックIPをメモしてください。 そして以下のようにsshコマンド実行してみてください。

bash
ssh -i HelloKey.pem ec2-user@<EC2のパブリックIP>

次のように表示されたら成功です。

結果
      __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|
[ec2-user@ip-10-0-198-184 ~]$ 

CDKでAWSのEC2を作成し、アクセスすることができました。やったー。

4, インスタンスを削除する

EC2が不要になったらcdkコマンドで削除することができます。 次のコマンドで削除できます。

bash
cdk destroy

削除が完了されたら、AWSコンソールを開いて本当に削除されているか確認してみてください。 跡形もなく削除されていると思います。かんたん。

プロフィール写真

Soraef

ソフトウェアエンジニア。趣味は競馬、写真、ゲーム。

お問い合わせはTwitterのDMでお願いします。