🐷
【AWS入門】EC2(+Nginx)を立ててみた #Terraform編
1. はじめに
こんにちは!ta8i2chi8です。
AWS学習日記の第二弾です。
前回、EC2にNginxをインストールした簡単なWebサーバーの構築をGUIで実施しました。
今回は、Terraformを使って構築してみたいと思います。
今回構築したい構成(前回と同様)
ソースコード(完成版)はこちら
2. 前提条件
- AWSアカウントを作成済みであること
- Terraformを使用できる環境があること
3. ディレクトリ構造
- modules
- compute
- main.tf # コンピューティングリソース
- outputs.tf # コンピューティングリソースの出力
- variables.tf # コンピューティングリソースの入力
- network
- main.tf # ネットワークリソース
- outputs.tf # ネットワークリソースの出力
- variables.tf # ネットワークリソースの入力
- backend.tf # tfstateの設定(保存先など)
- provider.tf # providerの設定
- main.tf # モジュールの呼び出し
以下ブログを参考に、moduleディレクトリ内でmoduleブロックを定義して呼び出す形式を採用しました。
現段階ではmoduleに分ける必要はないかもしれないですが、実務を想定してこの形で実装しています。
4. 各ファイルの実装
/module/compute/main.tf
data "aws_ssm_parameter" "amzn2" {
name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
}
resource "aws_instance" "web_server" {
ami = data.aws_ssm_parameter.amzn2.value
instance_type = "t2.micro"
subnet_id = var.subnet_id
vpc_security_group_ids = [aws_security_group.web_server.id]
# キーペアのみマネージメントコンソールで作成しておく必要あり。ここでは作成済のキーペア名を入力する。
key_name = "nginx-web-server-key"
associate_public_ip_address = true
tags = {
Name = "${var.pj_name}-ec2"
}
user_data = <<-EOF
#!/bin/bash
sudo yum update -y
sudo amazon-linux-extras install nginx1 -y
sudo yum install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx
EOF
}
resource "aws_security_group" "web_server" {
name = "${var.pj_name}-sg"
description = "${var.pj_name} sg"
vpc_id = var.vpc_id
tags = {
Name = "${var.pj_name}-sg"
}
}
resource "aws_vpc_security_group_ingress_rule" "web_server" {
count = length(var.security_group_ingress_rules)
security_group_id = aws_security_group.web_server.id
cidr_ipv4 = var.security_group_ingress_rules[count.index].cidr
ip_protocol = "TCP"
from_port = var.security_group_ingress_rules[count.index].from_port
to_port = var.security_group_ingress_rules[count.index].to_port
}
resource "aws_vpc_security_group_egress_rule" "web_server" {
security_group_id = aws_security_group.web_server.id
cidr_ipv4 = "0.0.0.0/0"
ip_protocol = "-1"
from_port = "0"
to_port = "0"
}
/module/compute/outputs.tf
# 記述なし
/module/compute/variables.tf
variable "pj_name" {
type = string
description = "PJ名"
}
variable "vpc_id" {
type = string
description = "VPCのID"
}
variable "subnet_id" {
type = string
description = "サブネットのID"
}
variable "security_group_ingress_rules" {
type = list(
object({
cidr = string
from_port = string
to_port = string
})
)
}
/module/network/main.tf
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "${var.pj_name}-vpc"
}
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${var.pj_name}-igw"
}
}
# パブリックサブネット
resource "aws_subnet" "public_1a" {
vpc_id = aws_vpc.main.id
cidr_block = var.subnet_cidr
availability_zone = "ap-northeast-1a"
tags = {
Name = "${var.pj_name}-subnet"
}
}
# パブリックサブネット用RT
resource "aws_route_table" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${var.pj_name}-rt"
}
}
resource "aws_route" "default_route" {
route_table_id = aws_route_table.main.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
resource "aws_route_table_association" "public_1a" {
subnet_id = aws_subnet.public_1a.id
route_table_id = aws_route_table.main.id
}
/module/network/outputs.tf
output "vpc_id" {
value = aws_vpc.main.id
description = "VPCのID"
}
output "subnet_id" {
value = aws_subnet.public_1a.id
description = "サブネットのID"
}
/module/network/variables.tf
variable "pj_name" {
type = string
description = "PJ名"
}
variable "vpc_cidr" {
type = string
description = "VPCのCIDR"
}
variable "subnet_cidr" {
type = string
description = "サブネットのCIDR"
}
backend.tf
# ちゃんとリモートで管理したいときはコメントアウト解除
# terraform {
# backend "s3" {
# bucket = "*****-tfstate"
# key = "*****/terraform.tfstate"
# encrypt = true
# dynamodb_table = "*****-tfstate-lock"
# region = "ap-northeast-1"
# }
# }
provider.tf
terraform {
required_version = "= 1.9.8"
required_providers {
aws = {
version = "= 5.78.0"
source = "hashicorp/aws"
}
}
}
provider "aws" {
region = "ap-northeast-1"
default_tags {
tags = {
owner = "tm"
}
}
}
main.tf
# マイIPを外部から取得
data "http" "my_ip" {
url = "https://ifconfig.me"
}
module "network" {
source = "./modules/network"
pj_name = "training-tf"
vpc_cidr = "13.0.0.0/16"
subnet_cidr = "13.0.0.0/24"
}
module "compute" {
source = "./modules/compute"
pj_name = "training-tf"
vpc_id = module.network.vpc_id
subnet_id = module.network.subnet_id
security_group_ingress_rules = [
{
cidr = "${data.http.my_ip.response_body}/32"
from_port = "22"
to_port = "22"
},
{
cidr = "0.0.0.0/0"
from_port = "80"
to_port = "80"
}
]
}
5. Terraformの初期化
以下コマンドを実行します。
terraform init
6. リソースの作成
以下コマンドを実行します。
terraform apply
7. ブラウザからの動作確認
GUI編と同様、ブラウザを開き、以下URLにアクセスしてNginxのデフォルトページが表示されるか確認します。
http://インスタンスのパブリックIP
以下のような画面が表示されれば無事Nginxサーバが完成しました!
不要であれば、リソースを削除しましょう。
terraform destroy
8. おわりに
今回は、Terraformを使ってEC2でNginxサーバーを構築してみました。
最後まで、読んでいただきありがとうございました!
参考
Discussion