ソースコードから理解する技術-UnderSourceCode

手を動かす(プログラムを組む)ことで技術を理解するブログ

aws cdk でVPCの中にEC2を立ててみた

aws cdkを使い、VPCの中にEC2を立ててみました。よくあるパターンなので既に色んな記事が書かれていますが、以下の点を工夫してみました。

※少し改修して記事にも反映しました

  • セキュリティグループを新規に作るが、Ingressはデフォルトでは何も許可しない(EC2に接続するときに手動で自分のIPのみ許可する運用を想定)
  • キーペアは別に作っておき、定義ファイルにてキーペア名を指定
  • デプロイするstage(dev、prdなど)毎に定義ファイルを用意する
    • EC2のベースとなるAMIのIDを定義ファイルで指定
    • キーペアも定義ファイルで指定
  • 実行時、デプロイ対象のstage、~/.aws/credentials のprofileを指定する

以下、CDKのソースについてです。またこちらにも上げてあります。
GitHub - SrcHndWng/cdk-vpc-ec2 at v1.1.0

実装について

CDKのプロジェクトを作り、変更したのは

  • lib/cdk-vpc-ec2-stack.ts ・・・ 変更
  • .config/config-dev.json ・・・ 追加

です。それぞれのソースを表示します。

lib/cdk-vpc-ec2-stack.ts

import cdk = require('@aws-cdk/core');
import ec2 = require('@aws-cdk/aws-ec2')
import fs = require('fs');

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

    // The code that defines your stack goes here

    const stage: string = this.node.tryGetContext("stage") ? this.node.tryGetContext("stage") : 'dev';
    const config = JSON.parse(fs.readFileSync(`.config/config-${stage}.json`, {encoding: 'utf-8'}));

    const vpc = new ec2.Vpc(this, 'myVpc', {
      cidr: '10.0.0.0/16',
    })

    // vpc has no inbound rules.
    const securityGroup = new ec2.SecurityGroup(this, 'mySecurityGroup', {
      vpc: vpc,
      securityGroupName: 'mySecurityGroup',
    })

    const instance = new ec2.CfnInstance(this, 'myEC2', {
      imageId: config.ami,
      instanceType: 't2.micro',
      keyName: config.keyName,
      subnetId: vpc.publicSubnets[0].subnetId,
      securityGroupIds: [securityGroup.securityGroupId]
    })

    new cdk.CfnOutput(this, 'stage', { value: stage })
    new cdk.CfnOutput(this, 'VPC', { value: vpc.vpcId })
    new cdk.CfnOutput(this, 'Security Group', { value: securityGroup.securityGroupId })
    new cdk.CfnOutput(this, 'EC2 PublicIP', { value: instance.attrPublicIp })
  }
}

こんな感じとなりました。VPC、SecurityGroup、EC2の順に作成しているのが分かるかと思います。またstageを取得し(デフォルトは「dev」として)、config-{stage}.jsonを読み込んでいることも分かるかと思います。

.config/config-dev.json

{
    "ami": "your-favorite-ami-id",
    "keyName": "your-key-name"
}

こちらは「.config」フォルダを作り、新規に作成しました。AMIのIDと、EC2のキーペア名を定義します。ファイル名の「-dev」の部分は、stage名としてください。例えば本番用なら「config-prd.json」として、後述する実行時にstageを指定します。

実行

http://undersourcecode.hatenablog.com/entry/2019/12/12/212936
こちらの前回と同様に、npxでインストールしたので、実行時にもnpxを指定します。

ビルド、CloudFormationの作成、デプロイの順で、以下のコマンドで実行できます。stage、~/.aws/creadentialsのプロファイルを指定します。

$ npm run build
$ npx cdk synth -c stage=dev --profile your_profile
$ npx cdk deploy -c stage=dev --profile your_profile

デプロイし、セキュリティグループに自分のIPを許可し、SSHなどで接続できることが確認できたら成功です。