LocalStackでEC2を構築する

※本ブログはアフィリエイトで収益を得ています

はじめに

今回はLocalStack上でTerraformを使いEC2を構築する手順をまとめます。

手順

EC2インスタンス用のAMI作成

LocalStackでEC2を使おうとTerraformのコードを書いてたところ、「AMI」を指定する必要があることに気づきました。どうやらAMIは自分で用意する必要があるようで、正解に辿り着くのに時間がかかってしまったため、備忘録がてら手順をまとめます。

AMIの元になるdocker imageのダウンロード

下記コマンドを使い、UbuntuのLunarをダウンロードします。

docker pull ubuntu:lunar

AMIのタグ付け

上記公式サイトにある通り、LocalStackでAMIとして扱えるよう、下記コマンドを実行します。これで使えるようになりました。

docker tag ubuntu:lunar localstack-ec2/ubuntu-focal-ami:ami-000001

Terraformのコードを書く

コードを下記の通りです。

# AWSプロバイダの設定。LocalStackを指すためにカスタムエンドポイントを使用。
provider "aws" {
  region                      = "us-east-1" # 使用するリージョンを指定
  access_key                  = "mock_access_key" # LocalStackではダミーのアクセスキーを使用
  secret_key                  = "mock_secret_key" # LocalStackではダミーのシークレットキーを使用
  skip_credentials_validation = true # ローカル環境のため、クレデンシャル検証をスキップ
  skip_metadata_api_check     = true # メタデータAPIのチェックをスキップ
  skip_requesting_account_id  = true # アカウントIDのリクエストをスキップ
  endpoints {
    ec2 = "http://localhost:4566" # LocalStackのエンドポイント設定
  }
}

# VPCリソースの作成
resource "aws_vpc" "example_vpc" {
  cidr_block = "10.0.0.0/16" # VPCのCIDRブロックを指定
}

# ネットワークACLリソースの作成
resource "aws_network_acl" "example_acl" {
  vpc_id = aws_vpc.example_vpc.id # 上で作成したVPCに紐付け

  # アウトバウンドルールの設定
  egress {
    action     = "allow" # トラフィックを許可
    protocol   = "-1" # すべてのプロトコルを指定
    rule_no    = 100 # ルール番号
    cidr_block = "0.0.0.0/0" # すべてのIP範囲を指定
    from_port  = 0 # すべてのポートを指定
    to_port    = 0 # すべてのポートを指定
  }

  # インバウンドルールの設定
  ingress {
    action     = "allow" # トラフィックを許可
    protocol   = "-1" # すべてのプロトコルを指定
    rule_no    = 100 # ルール番号
    cidr_block = "0.0.0.0/0" # すべてのIP範囲を指定
    from_port  = 0 # すべてのポートを指定
    to_port    = 0 # すべてのポートを指定
  }

  # タグの設定
  tags = {
    Name = "example_acl" # タグ名
  }
}

# サブネットの作成
resource "aws_subnet" "example_subnet" {
  vpc_id     = aws_vpc.example_vpc.id # 上で作成したVPCに紐付け
  cidr_block = "10.0.1.0/24" # サブネットのCIDRブロックを指定

  tags = {
    Name = "example_subnet" # タグ名
  }
}



/* SubnetにACL設定をすることはLocakStackでは未対応らしい
resource "aws_network_acl_association" "example_association" {
  subnet_id      = aws_subnet.example_subnet.id # 上で作成したサブネットを指定
  network_acl_id = aws_network_acl.example_acl.id # 上で作成したネットワークACLを指定
}
*/

# SSH接続を許可するセキュリティグループの作成
resource "aws_security_group" "allow_ssh" {
  name        = "allow_ssh"
  description = "Allow SSH inbound traffic"
  vpc_id      = aws_vpc.example_vpc.id

  # SSH接続を許可するインバウンドルール
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  # すべてのアウトバウンドトラフィックを許可
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# EC2インスタンスにセキュリティグループを関連付け
resource "aws_instance" "example_ec2" {
  ami                    = "ami-000001"
  instance_type          = "t2.micro"
  subnet_id              = aws_subnet.example_subnet.id
  vpc_security_group_ids = [aws_security_group.allow_ssh.id]

  tags = {
    Name = "example_instance1"
  }
}

と、実際に書いてわかったのは下記の通りです。

  • LocalStackではSubnetにACL設定をすることは未対応らしい
  • LocalStackではEC2インスタンスでアプリケーション構築はできない

どうやら実際に動くアプリケーションを構築するにはLambdaを使うのが良さそうです。

まとめ

LocalStackでEC2を使うための手順をまとめました。しかし、実際のAWS環境に比べ制約が多いため、実際のアプリケーション構築にはLambdaを使うのが良さそうです。