あめがえるのITブログ

頑張りすぎない。ほどほどに頑張るブログ。

【AWS】TerraformでVPC環境とSSMで接続できるEC2インスタンスを作成してみた


なんとなく普段作っているがどこにも保存してなかったので書いてみた。

実践!

1.Terraformコード作成
1-1.下記ファイルを作成
version.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  required_version = ">= 1.0.0"
}

variables.tf

variable "env" {
  type = map(any)
  default = {
    env = "test"
  }
}

variable "region" {
  description = "The AWS region to deploy resources in"
  type        = string
  default     = "ap-northeast-1"
}

variable "vpc_network" {
  type = map(any)

  default = {
    ser01 = "10.2.160.0/21"
  }
}

variable "area" {
  type = map(any)

  default = {
    region = "ap-northeast-1"
    az01   = "ap-northeast-1a"
    az02   = "ap-northeast-1c"
  }
}

variable "sub_network" {
  type = map(any)

  default = {
    pub_st-01 = "10.2.162.0/24"
    pub_st-02 = "10.2.163.0/24"

    pub_dy-01 = "10.2.160.0/24"
    pub_dy-02 = "10.2.161.0/24"

    pri_st-01 = "10.2.166.0/24"
    pri_st-02 = "10.2.167.0/24"

    pri_dy-01 = "10.2.164.0/24"
    pri_dy-02 = "10.2.165.0/24"
  }
}

provider.tf

provider "aws" {
  profile = "testvault"
  region  = "ap-northeast-1"
}

data.tf

data "aws_caller_identity" "current" {}

main.tf

resource "aws_vpc" "vpc01" {
  cidr_block           = var.vpc_network["ser01"]
  enable_dns_hostnames = true

  tags = {
    Name = "${var.env["env"]}vpc01"
  }
}

resource "aws_subnet" "dyprsub01" {
  vpc_id            = aws_vpc.vpc01.id
  cidr_block        = var.sub_network["pri_dy-01"]
  availability_zone = var.area["az01"]

  tags = {
    Name = "${var.env["env"]}dyprsub01"
  }
}

resource "aws_subnet" "dyprsub02" {
  vpc_id            = aws_vpc.vpc01.id
  cidr_block        = var.sub_network["pri_dy-02"]
  availability_zone = var.area["az02"]

  tags = {
    Name = "${var.env["env"]}dyprsub02"
  }
}

resource "aws_subnet" "dypusub01" {
  vpc_id            = aws_vpc.vpc01.id
  cidr_block        = var.sub_network["pub_dy-01"]
  availability_zone = var.area["az01"]

  tags = {
    Name = "${var.env["env"]}dypusub01"
  }
}

resource "aws_subnet" "dypusub02" {
  vpc_id            = aws_vpc.vpc01.id
  cidr_block        = var.sub_network["pub_dy-02"]
  availability_zone = var.area["az02"]

  tags = {
    Name = "${var.env["env"]}dypusub02"
  }
}

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.vpc01.id

  tags = {
    Name = "${var.env["env"]}igw"
  }
}

resource "aws_eip" "nat_eip" {
  domain = "vpc"
}

resource "aws_nat_gateway" "nat_gw" {
  allocation_id = aws_eip.nat_eip.id
  subnet_id     = aws_subnet.dypusub01.id

  tags = {
    Name = "${var.env["env"]}nat-gw"
  }
}

resource "aws_route_table" "public_rt" {
  vpc_id = aws_vpc.vpc01.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }

  tags = {
    Name = "${var.env["env"]}public_rt"
  }
}

resource "aws_route_table_association" "public_rt_assoc" {
  subnet_id      = aws_subnet.dypusub01.id
  route_table_id = aws_route_table.public_rt.id
}

resource "aws_route_table" "private_rt" {
  vpc_id = aws_vpc.vpc01.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat_gw.id
  }

  tags = {
    Name = "${var.env["env"]}private_rt"
  }
}

resource "aws_route_table_association" "private_rt_assoc" {
  subnet_id      = aws_subnet.dyprsub01.id
  route_table_id = aws_route_table.private_rt.id
}

resource "aws_iam_role" "ec2_ssm_role" {
  name = "${var.env["env"]}ec2_ssm_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = {
        Service = "ec2.amazonaws.com"
      }
    }]
  })
}

resource "aws_iam_policy_attachment" "ec2_ssm_role_attachment" {
  name       = "${var.env["env"]}ec2_ssm_role_attachment"
  policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
  roles      = [aws_iam_role.ec2_ssm_role.name]
}

resource "aws_instance" "example_ec2" {
  ami                    = "ami-00c79d83cf718a893"
  instance_type          = "t3.micro"
  subnet_id              = aws_subnet.dyprsub01.id
  iam_instance_profile   = aws_iam_instance_profile.example_profile.name
  vpc_security_group_ids = [aws_security_group.example_sg.id]

  root_block_device {
    encrypted = true
  }
  metadata_options {
    http_tokens = "required"
  }

  tags = {
    Name = "${var.env["env"]}example_ec2"
  }
}

resource "aws_iam_instance_profile" "example_profile" {
  name = "${var.env["env"]}example_profile"
  role = aws_iam_role.ec2_ssm_role.name
}

resource "aws_security_group" "example_sg" {
  vpc_id = aws_vpc.vpc01.id
  description = "Security group for example application"

  ingress {
    from_port   = 443
    to_port     = 443
    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"]
  }

  tags = {
    Name = "${var.env["env"]}example_sg"
  }
}


2.terraform実行
2-1.下記を実行

> terraform fmt
※コード成形
> terraform init
> terraform plan
> terraform apply


3.SSM接続
3-1.AWS - EC2 - 左ペインから「インスタンス」を選択

3-2.作成したインスタンスのIDを選択

3-3.「接続」

3-4.「セッションマネージャ」タブを選択し、「接続」

3-5.セッションマネージャに接続できることを確認


4.削除
※NATGatewayも作っているので使い終わったらすぐ消しましょう。
4-1.下記を実行

> terraform destroy



感想