📝
Terraform EC2構築 × Ansible Nginxインストール
Terraform構築
基本コマンド
# aws configure profile作成 profile名:default
$ aws configure --profile default
# aws configure 確認・編集
$ vim ~/.aws/credentials
# aws configure 削除
$ rm -r ~/.aws
# terraformでモジュール単位でリソース作成
$ terraform apply -target module.VPC
# Ansible Role作成
$ ansible-galaxy init nginx
ディレクトリ構成
tree
├── backend.tf
├── main.tf
├── modules
│ ├── alb
│ │ ├── alb.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── ec2
│ │ ├── ec2.tf
│ │ └── variables.tf
│ ├── security_group
│ │ ├── outputs.tf
│ │ ├── security-group.tf
│ │ └── variables.tf
│ └── vpc
│ ├── outputs.tf
│ └── vpc.tf
backend.tf
provider "aws" {
region = "ap-northeast-1"
}
terraform {
backend "s3" {
bucket = "tfstate-s3bucket" // 事前にs3バケットを作成する
key = "terraform.tfstate"
shared_credentials_file = "~/.aws/credentials"
profile = "default" // 事前にprofile作成する
region = "ap-northeast-1"
}
}
main.tf
module vpc {
source = "./modules/vpc"
}
module security_group {
source = "./modules/security_group"
config = {
// vpc.tfでoutputする
vpc_id = module.vpc.vpc_id
}
}
module ec2 {
source = "./modules/ec2"
config = {
// vpc.tfでoutputする
subnet-a_id = module.vpc.subnet-a_id
subnet-c_id = module.vpc.subnet-c_id
security_group_id = module.security_group.security_group_id
}
}
module alb {
source = "./modules/alb"
config = {
// vpc.tfでoutputする
vpc_id = module.vpc.vpc_id
subnet-a_id = module.vpc.subnet-a_id
subnet-c_id = module.vpc.subnet-c_id
// security_group.tfでoutputする
security_group_id = module.security_group.security_group_id
}
}
vpcモジュール
## VPCの設定
resource "aws_vpc" "public-vpc" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "public-vpc"
}
}
##サブネットの作成
resource "aws_subnet" "public-subnet-a" {
vpc_id = aws_vpc.public-vpc.id
cidr_block = "10.0.16.0/24"
availability_zone = "ap-northeast-1a"
tags = {
Name = "public-subnet-a"
}
}
resource "aws_subnet" "public-subnet-c" {
vpc_id = aws_vpc.public-vpc.id
cidr_block = "10.0.32.0/24"
availability_zone = "ap-northeast-1c"
tags = {
Name = "public-subnet-c"
}
}
##ルートテーブルの追加(0.0.0.0/0)
resource "aws_route_table" "public-route" {
vpc_id = aws_vpc.public-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.example_GW.id
}
}
##ルートテーブルの追加
resource "aws_route_table_association" "puclic-subnet-a" {
subnet_id = aws_subnet.public-subnet-a.id
route_table_id = aws_route_table.public-route.id
}
resource "aws_route_table_association" "puclic-subnet-c" {
subnet_id = aws_subnet.public-subnet-c.id
route_table_id = aws_route_table.public-route.id
}
##ゲートウェイの設定
resource "aws_internet_gateway" "example_GW" {
vpc_id = aws_vpc.public-vpc.id
}
output "vpc_id" {
value = aws_vpc.public-vpc.id
}
output "subnet-a_id" {
value = aws_subnet.public-subnet-a.id
}
output "subnet-c_id" {
value = aws_subnet.public-subnet-c.id
}
security_groupモジュール
## security group
resource "aws_security_group" "example_SG" {
name = "example_SG"
description = "example_SG"
vpc_id = var.config.vpc_id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
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"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "example_SG"
}
}
variable "config" {
type = object({
vpc_id = string
})
}
output "security_group_id" {
value = aws_security_group.example_SG.id
}
EC2モジュール
##EC2(example_EC2)
resource "aws_instance" "example_EC2" {
ami = var.ami
instance_type = var.instance_type
disable_api_termination = false
key_name = "EC2-key"
vpc_security_group_ids = [var.config.security_group_id]
subnet_id = var.config.subnet-a_id
root_block_device {
volume_type = "gp2"
volume_size = var.volume_size
}
tags = {
Name = "example_EC2"
}
}
##EIP(example_EC2)
resource "aws_eip" "example_EC2" {
instance = "${aws_instance.example_EC2.id}"
vpc = true
}
variable "config" {
type = object({
subnet-a_id = string
subnet-c_id = string
security_group_id = string
})
}
variable "ami" {
default = "ami-XXXXXXXXXXXX"
}
variable "instance_type" {
default = "t2.micro"
}
variable "volume_size" {
default = "8"
}
ALBモジュール
resource "aws_alb" "alb" {
name = "alb"
security_groups = [var.config.security_group_id]
subnets = [var.config.subnet-a_id, var.config.subnet-c_id]
internal = false
enable_deletion_protection = false
}
resource "aws_alb_target_group" "target-group" {
name = "target-group"
depends_on = [aws_alb.alb]
port = 80
protocol = "HTTP"
vpc_id = var.config.vpc_id
target_type = "ip"
health_check {
protocol = "HTTP"
path = "/ping"
port = 80
unhealthy_threshold = 5
timeout = 5
interval = 10
matcher = 200
}
}
resource "aws_alb_listener" "listener" {
load_balancer_arn = aws_alb.alb.arn
port = 80
protocol = "HTTP"
default_action {
target_group_arn = aws_alb_target_group.target-group.arn
type = "forward"
}
}
resource "aws_alb_listener_rule" "rule" {
depends_on = [aws_alb_target_group.target-group]
listener_arn = aws_alb_listener.listener.arn
priority = 100
action {
type = "forward"
target_group_arn = aws_alb_target_group.target-group.arn
}
condition {
path_pattern {
values = ["*"]
}
}
}
variable "config" {
type = object({
vpc_id = string
subnet-a_id = string
subnet-c_id = string
security_group_id = string
})
}
output "dns_name" {
value = aws_alb.alb.dns_name
}
ansible構築
ディレクトリ構成
Role作成
$ ansible-galaxy init nginx
tree
├── nginx
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ ├── tests
│ │ ├── inventory
│ │ └── test.yml
│ └── vars
│ └── main.yml
├── playbook.yml
├── aws_ec2.yml
aws_ec2.yml
plugin: aws_ec2
aws_access_key_id: XXXXXXXX
aws_secret_access_key: XXXXXXXX
aws_security_token:
regions:
- ap-northeast-1
hostnames:
- tag:Name
groups:
nginx: "'<EC2インスタンス名>' in tags.Name"
compose:
ansible_host: public_ip_address
playbook.yml
- hosts: nginx
become: true
vars_files:
- ./nginx/vars/main.yml
roles:
- nginx
Nginx Role
- name: Enable amzn2extra-nginx1.12 repository
shell: amazon-linux-extras enable nginx1.12
changed_when: false
- name: Install Nginx packages from amazon-linux-extras
yum:
name: nginx
state: present
# vars file for nginx
ansible_ssh_user: ec2-user
ansible_ssh_private_key_file: ~/.ssh/EC2-key.pem
実行コマンド
$ ansible-playbook -i aws_ec2.yml playbook.yml
参考文献
- AnsibleでEC2のAmazon Linux 2にNginxをインストールする方法の検討(古いJinja2でもOK)
- AnsibleでAmazonLinux2 + Laravel + mysql5.7 + nginx + SSL環境を構築する。
- 【AWS・Ansible】 コマンド1つでAmazon EC2インスタンス作成
- Ansibleでnginx+php構築
- TerraformでALBを作成する
- 特定のresourceだけ terraform {plan|apply} したい
- Ansibleでできることを中の人が教えます - インストールと実行~EC2へのNginx投入までを学ぼう
- [Terraform][Backends][v0.9]tfstateファイルの管理方法
Discussion