×
採用サイトはこちら

TypeScriptで挑戦!AWS CDKでWebサーバー構築!

はじめに

前回の記事AWS CDK (TypeScript) でインフラ構築【用語解説・ハンズオン】では、AWS CDKの基本概念と環境構築、S3バケットの作成・削除を体験しました。

今回はその続編として、VPCとEC2を作成してWebサーバーを立ち上げることに挑戦します。

私がCDKでWebサーバーを構築しようと思ったのは、インフラをコードで管理することで、構築や削除の手間が省けるだけではなく、保守の面でもメリットがあることを知ったからです。
今回のケースだと、ネットワーク設定(VPC・セキュリティグループなど)とWebサーバーの設定(マシンイメージ・UserDataなど)の現状が、手元のTypeScriptコードを読むだけで把握できます。

TypeScriptコードで複雑なネットワーク構成やWebサーバー構築も自動化できるCDKの手軽さをぜひ体感してください!

目次

今回構築するアーキテクチャの概要

今回は、Webサーバーをインターネットに公開するための基本的なネットワーク構成を構築します。

  • VPC (Virtual Private Cloud): AWS上に論理的に分離された仮想ネットワークを作成します。
  • パブリックサブネット: インターネットと直接通信できるネットワークの区画です。
  • Internet Gateway: VPC内のリソースがインターネットと通信するための出入り口です。
  • EC2 (Elastic Compute Cloud): クラウド上の仮想サーバーです。ここにWebサーバーを構築します。
  • Security Group: インスタンスの仮想ファイアウォールです。今回はWebアクセス用のHTTP(80番ポート)を許可します。

💡 CDKが裏側で自動作成してくれるリソースについての補足
CDKの強力な機能の1つが「L2 Construct(上位抽象化コンポーネント)」です。
VPCを作成するコードを数行書くだけで、CDKは裏側で自動的にルートテーブルの作成やインターネットゲートウェイのアタッチなど、AWSのベストプラクティスに基づいた設定をよしなに組み上げてくれます。

ハンズオンの手順

手順の流れ

本記事のハンズオンは以下のステップで進めます。

Step内容
事前準備CDK実行環境の確認
Step 1VPCとセキュリティグループの定義
Step 2EC2インスタンスの定義と設定
Step 3デプロイと動作確認
Step 4リソースの削除(クリーンアップ)

イメージ図

本手順のイメージ図は以下になります。
AWS CDKは、TypeScriptコードからCloudFormationテンプレートを自動生成し、CloudFormation経由でリソースを作成します。

ハンズオン前準備(環境構築)

CDKの実行環境(Node.js、AWS CLI、AWS CDKのインストールと認証設定)がまだ整っていない方は、前回の記事の「ハンズオンStep1(環境構築)」を参照してください。
今回は、初期化して生成された lib/ フォルダ配下のスタックファイル(例: cdk-handson-stack.ts)にコードを追記していく形で進めます。

VPCとセキュリティグループの定義

それでは、実際にTypeScriptでコードを記述していきましょう。
lib/ ディレクトリ配下のスタックファイル(例: lib/cdk-handson-stack.ts)を開き、以下のコードを記述します。

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2'; // EC2・VPC関連のモジュールをインポート

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

    // ==========================================
    // 1. VPCの作成
    // ==========================================
    const vpc = new ec2.Vpc(this, 'HandsonVpc', {
      ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'),
      maxAzs: 1, // 今回は検証用のため1つのアベイラビリティゾーンを使用
      subnetConfiguration: [
        {
          cidrMask: 24,
          name: 'PublicSubnet',
          subnetType: ec2.SubnetType.PUBLIC, // パブリックサブネットを指定
        }
      ],
      natGateways: 0, // ※重要: ハンズオンのコスト削減のためNAT Gatewayは作成しない
    });

    // ==========================================
    // 2. セキュリティグループの作成
    // ==========================================
    const webSg = new ec2.SecurityGroup(this, 'WebSecurityGroup', {
      vpc,
      securityGroupName: 'web-sg',
      description: 'Allow HTTP traffic to EC2 instance',
      allowAllOutbound: true, 
    });

    // インターネット(0.0.0.0/0)からのHTTP(80番ポート)通信を許可
    webSg.addIngressRule(
      ec2.Peer.anyIpv4(),
      ec2.Port.tcp(80),
      'Allow HTTP traffic from anywhere'
    );
  }
}

ポイント解説

  • VPCの作成: new ec2.Vpc を呼び出すだけでVPCが作成されます。
    また、今回は学習目的での無駄な課金を防ぐため、料金が比較的高価なNAT Gatewayを作成しない設定(natGateways: 0)にしています。
  • セキュリティグループ: Webブラウザからアクセスできるように、インバウンドルール(受信トラフィック)としてTCPの80番ポート(HTTP)を 0.0.0.0/0(すべてのIP)から許可しています。

EC2インスタンスの定義と設定

次に、作成したVPC内にEC2インスタンスを配置し、起動時に自動でWebサーバーが立ち上がるように設定します。 先程のコードの続きに以下を追記します。

    // ==========================================
    // 3. EC2インスタンスの作成
    // ==========================================
    const webInstance = new ec2.Instance(this, 'WebServerInstance', {
      vpc,
      instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO), // 無料枠で使える t3.micro
      machineImage: ec2.MachineImage.latestAmazonLinux2023(), // 最新のAmazon Linux 2023を使用
      securityGroup: webSg,
      vpcSubnets: {
        subnetType: ec2.SubnetType.PUBLIC, // パブリックサブネットに配置
      },
    });

    // ==========================================
    // 4. UserData(起動時スクリプト)の設定
    // ==========================================
    // インスタンス起動時にApache(httpd)をインストールして起動する
    webInstance.userData.addCommands(
      'dnf update -y',
      'dnf install -y httpd',
      'systemctl start httpd',
      'systemctl enable httpd',
      'echo "<h1>Hello AWS CDK! Web Server is running!</h1>" > /var/www/html/index.html'
    );

    // ==========================================
    // 5. CfnOutput(デプロイ結果の出力)
    // ==========================================
    // デプロイ完了時にEC2のパブリックIPアドレスをターミナルに表示する
    new cdk.CfnOutput(this, 'WebInstancePublicIp', {
      value: `http://${webInstance.instancePublicIp}`,
      description: 'Access the web server using this URL',
    });

ポイント解説

  • インスタンスタイプとOS: 無料利用枠の対象となることが多い t3.micro と、最新の Amazon Linux 2023 を指定しています。

  • UserDataの利用: userData.addCommands を使用すると、EC2インスタンスの初回起動時に実行されるシェルスクリプト(UserData)を定義できます。
    ここではWebサーバーソフトウェア(Apache HTTP Server)のインストール、自動起動設定、そしてテスト用HTMLファイルの作成を記述しています。
  • CfnOutput: デプロイが完了した際、コンソール画面に作成されたEC2の「パブリックIPアドレス(アクセス用URL)」を自動で出力させる便利な機能です。

デプロイと動作確認

差分の確認

コードの記述が完了したら、まずデプロイ前に cdk diff コマンドで、現在のAWS環境との差分(追加・変更されるリソース)を確認しましょう。

cdk diff

VPCやEC2などの追加予定リソースが一覧表示されます。
意図しない変更が含まれていないか確認してからデプロイに進みましょう。

デプロイの実行

差分の確認が取れたら、AWS環境へデプロイします。ターミナルで以下のコマンドを実行します。

cdk deploy

途中でセキュリティに関する変更(IAMロールやセキュリティグループの作成など)の確認を求められる場合があります。その際は y を入力して進めてください。
デプロイが完了すると、ターミナルの出力の最後に以下のようなOutputsが表示されます。

Outputs:
CdkEc2HandsonStack.WebInstancePublicIp = http://198.51.100.123

ブラウザで動作確認

Outputs に表示された URL(http://198.51.100.123 の部分は環境によって異なります)をブラウザで開いてみてください。

「Hello AWS CDK! Web Server is running!」

という文字が書かれたテストページが表示されれば、ハンズオンは大成功です!
VPC、EC2の構築からWebサーバーの立ち上げまでが、すべてコードによって自動で完了しました。

リソースの削除(クリーンアップ)

動作確認が終わったら、AWSの課金が発生しないように、作成したリソースを削除しておきましょう。
AWS CDKを使えば、リソースの削除もコマンド一つで簡単に行えます。

ターミナルで以下のコマンドを実行します。

cdk destroy

確認プロンプトが表示されたら y を入力します。
これで、VPC、EC2、セキュリティグループなど、今回作成したすべてのリソースがAWS上から綺麗に削除されます。 マネジメントコンソールから手動でリソースを削除する場合、関連付けられたリソースを順番に削除していく必要がありますが、CDKを使えば一括で削除してくれるため、消し忘れを防ぐことができます。

まとめ

今回は、AWS CDK(TypeScript)を用いて、Amazon VPCとAmazon EC2を構築し、UserDataを使ってWebサーバーを立ち上げるハンズオンを行いました。
CDKでリソースを作成して感じたメリットは以下の通りです。

  • 数行のTypeScriptコードを書くだけで、VPC、サブネット、インターネットゲートウェイなどが自動生成される
  • UserDataを使ってEC2起動時のミドルウェア設定もコード化できる
  • cdk deploy と cdk destroy で構築も削除もコマンド一発で簡単

実際にやってみて感じたのは、インフラをコード化することでコンソール画面から構築していた時より後から見返しやすいという点です。
チーム開発の場合でも、他の人が作成したインフラ構成を手元のコードで確認ができ、GitHub上でプルリクエストも作成できるので、レビューもしやすいです。
また、デプロイ前にcdk diff で変更内容を事前に確認できるので、安心してデプロイできると感じました。

少し難しそうに見えるインフラ構築も、CDKを使えばプログラミング感覚で楽しく構築できます。
ぜひご自身でもコードを書き換えながら、様々なAWSリソースの構築にチャレンジしてみてください!

We Are Hiring!

AWS CDKでVPCとEC2を構築し、インフラをコードで管理できる手軽さを体験してみて、この技術を仕事で活かしたいと感じた方もいるのではないでしょうか。

FindConsultingでは、AWS CDK・CloudFormation・TerraformによるIaCや、CodePipeline・CircleCIを用いたCI/CD構築、AWSを活用したWebサービスのアーキテクチャ設計・構築に携わるエンジニアが活躍しています。

こういったIaCを活かした仕事に興味がある方は、ぜひ一緒に働きませんか?

現在、FindConsultingではAWSやIaCに興味のある仲間を募集しています。
まずはカジュアル面談からでも、ぜひお気軽にお声がけください!

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

この記事を書いた人

弊社FindConsulting在籍のエンジニアです。
地方自治体向けSaaSのAWS移行プロジェクトに参画し、インフラ構築・リリース支援を担当し、IaCによるバッチ処理基盤の構築や自動デプロイ環境を整備しました。
また、小売業向けデータ分析基盤のPoC開発、大手情報サイトのAWSインフラ運用保守(障害対応、監視、SQLデータ修正)にも従事し、クラウドインフラとデータ関連の幅広い経験を保有しています。
本ブログでは、クラウドインフラ、CI/CD、データ連携に関する実践的な知見を発信します。

目次