🖥️

TerraformでEC2にWindows環境を立ててリモートデスクトップ接続する

2024/01/21に公開

参考

https://gmusumeci.medium.com/how-to-deploy-a-windows-server-ec2-instance-in-aws-using-terraform-dd86a5dbf731

環境

  • OS: macOS Ventura 13.5
  • AWS CLI: aws-cli/2.8.3 Python/3.9.11 Darwin/22.6.0 exe/x86_64 prompt/off
  • tfenv: tfenv 3.0.0
  • terraform: Terraform v1.6.6 on darwin_amd64

1. Terraform用のIAMユーザーを作成する

AWS Management Console でボタンぽちぽちでTerraform用のIAMユーザーを作成します。
ちなみに僕は、try-ec2-windows-terraformという名前で作成しました。

2. profileを設定する

設定する

コマンドを実行
aws configure --profile <profile_name>
値を入力
AWS Access Key ID [None]: <aws_access_key_id>
AWS Secret Access Key [None]: <aws_secret_access_key>
Default region name [None]: <region_name>
Default output format [None]: 
  • <profile_name>: try-ec2-windows-terraform
  • <aws_access_key_id>: IAMユーザーの画面で取得した値を入力
  • <aws_secret_access_key>: IAMユーザーの画面で取得した値を入力
  • <region_name>: ap-northeast-1

確認する

コマンドを実行
cat ~/.aws/config
出力例
...
[profile try-ec2-windows-terraform]
region = ap-northeast-1
コマンドを実行
cat ~/.aws/credentials
出力例
...
[try-ec2-windows-terraform]
aws_access_key_id = *****
aws_secret_access_key = *****

3. terraformを構成する

terraformを作成する

コマンドを実行
mkdir terraform
コマンドを実行
cd terraform

variables.tfを作成する

コマンドを実行
touch variables.tf
variables.tf
variable "profile" {
  type = string
}
variable "environment" {
  type = string
}
variable "project" {
  type = string
}

# Network
variable "availability_zone" {
  type = string
}
variable "vpc_cidr" {
  type = string
}
variable "public_subnet_cidr" {
  type = string
}

# Windows Virtual Machine
variable "windows_instance_type" {
  type = string
}
variable "windows_associate_public_ip_address" {
  type = bool
}
variable "windows_root_volume_size" {
  type = number
}
variable "windows_root_volume_type" {
  type = string
}
variable "windows_data_volume_size" {
  type = number
}
variable "windows_data_volume_type" {
  type = string
}

terraform.tfvarsを作成する

コマンドを実行
touch terraform.tfvars
terraform.tfvars
profile = "try-ec2-windows-terraform"
environment = "dev"
project = "try-ec2-windows"

# Network
availability_zone = "ap-northeast-1a"
vpc_cidr = "10.11.0.0/16"
public_subnet_cidr = "10.11.1.0/24"

# Windows Virtual Machine
windows_instance_type = "t3.micro"
windows_associate_public_ip_address = true
windows_root_volume_size = 30
windows_root_volume_type = "gp2"
windows_data_volume_size = 10
windows_data_volume_type = "gp2"

provider.tfを作成する

コマンドを実行
touch provider.tf
provider.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 4.49.0"
    }
  }

  required_version = "~> 1.6.0"
}

provider "aws" {
  profile = var.profile
}

network.tfを作成する

コマンドを実行
touch network.tf
network.tf
# Create the VPC
resource "aws_vpc" "vpc" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true
}
# Define the public subnet
resource "aws_subnet" "public-subnet" {
  vpc_id            = aws_vpc.vpc.id
  cidr_block        = var.public_subnet_cidr
  availability_zone = var.availability_zone
}
# Define the internet gateway
resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.vpc.id
}
# Define the public route table
resource "aws_route_table" "public-rt" {
  vpc_id = aws_vpc.vpc.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.gw.id
  }
}
# Assign the public route table to the public subnet
resource "aws_route_table_association" "public-rt-association" {
  subnet_id      = aws_subnet.public-subnet.id
  route_table_id = aws_route_table.public-rt.id
}

key-pair.tfを作成する

コマンドを実行
touch key-pair.tf
key-pair.tf
# Generates a secure private key and encodes it as PEM
resource "tls_private_key" "key_pair" {
  algorithm = "RSA"
  rsa_bits  = 4096
}
# Create the Key Pair
resource "aws_key_pair" "key_pair" {
  key_name   = "${var.environment}-${var.project}-windows-key-pair"  
  public_key = tls_private_key.key_pair.public_key_openssh
}
# Save file
resource "local_file" "ssh_key" {
  filename = "${aws_key_pair.key_pair.key_name}.pem"
  content  = tls_private_key.key_pair.private_key_pem
}

ami.tfを作成する

コマンドを実行
touch ami.tf
ami.tf
data "aws_ami" "windows-2022" {
  most_recent = true
  owners      = ["amazon"]
  filter {
    name   = "name"
    values = ["Windows_Server-2022-English-Full-Base*"]
  }
}

windows-vm.tfを作成する

コマンドを実行
touch windows-vm.tf
windows-vm.tf
# Define the security group for the Windows server
resource "aws_security_group" "aws-windows-sg" {
  name        = "${var.environment}-${var.project}-windows-sg"
  description = "Allow incoming connections"
  vpc_id      = aws_vpc.vpc.id
  ingress {
    from_port   = 3389
    to_port     = 3389
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Allow incoming RDP connections"
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  tags = {
    Name = "${var.environment}-${var.project}-windows-sg"
  }
}

# Create EC2 Instance
resource "aws_instance" "windows-server" {
  ami = data.aws_ami.windows-2022.id
  instance_type = var.windows_instance_type
  subnet_id = aws_subnet.public-subnet.id
  vpc_security_group_ids = [aws_security_group.aws-windows-sg.id]
  source_dest_check = false
  key_name = aws_key_pair.key_pair.key_name
  associate_public_ip_address = var.windows_associate_public_ip_address
  
  # root disk
  root_block_device {
    volume_size           = var.windows_root_volume_size
    volume_type           = var.windows_root_volume_type
    delete_on_termination = true
    encrypted             = true
  }
  # extra disk
  ebs_block_device {
    device_name           = "/dev/xvda"
    volume_size           = var.windows_data_volume_size
    volume_type           = var.windows_data_volume_type
    encrypted             = true
    delete_on_termination = true
  }
  
  tags = {
    Name        = "${var.environment}-${var.project}-windows-server-vm"
    Environment = var.environment
  }
}

4. デプロイする

terraform init

コマンドを実行
terraform init
出力例
...
Terraform has been successfully initialized!
...

terraform plan

コマンドを実行
terraform plan
出力例
...
Plan: 10 to add, 0 to change, 0 to destroy.
...

terraform apply

コマンドを実行
terraform apply
出力例
...
Apply complete! Resources: 10 added, 0 changed, 0 destroyed.

5. EC2が立ち上がっていることを確認する

6. リモートデスクトップ接続する

インスタンスIDをクリックして、インスタンス詳細ページに飛ぶ

「Connect」ボタンを押す

「RDP client」タブを押す

「Get password」を押す

terraform/dev-try-ec2-windows-windows-key-pair.pemを開いてコピーして、「ここ」にペーストする

「Decrypto password」ボタンを押す

passwordをコピーする

「Download remote desktop file」ボタンを押す

「dev-try-ec2-windows-windows-server-vm.rdp」ファイルがダウンロードされるので、それを開き、先ほどコピーしたpasswordをペーストし、「continue」ボタンを押す

接続完了🎉

7. お片付けする

Terraformで作った環境を削除する

削除する

コマンドを実行
terraform destroy
出力例
...
Destroy complete! Resources: 10 destroyed.

確認する

コマンドを実行
terraform show
出力例
The state file is empty. No resources are represented.

terraformディレクトリを削除する

コマンドを実行
cd ../
コマンドを実行
rm -rf terraform

登録したprofileを削除する

config内の記述を削除する

コマンドを実行
vi ~/.aws/config
~/.aws/config (例)
...
[profile try-ec2-windows-terraform] # <- この行を削除
region = ap-northeast-1 # <- この行を削除

credentials内の記述を削除する

コマンドを実行
vi ~/.aws/credentials
~/.aws/credentials (例)
...
[try-ec2-windows-terraform] # <- この行を削除
aws_access_key_id = ***** # <- この行を削除
aws_secret_access_key = ***** # <- この行を削除

作ったIAM userを削除する

AWS Management Console でぽちぽちして削除する

最後に

ありがとうございました😀

Discussion