LoginSignup
2
0

More than 3 years have passed since last update.

Terraform EC2構築 × Ansible Nginxインストール

Last updated at Posted at 2021-05-05

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

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

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モジュール

modules/vpc/vpc.tf
## 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
}
modules/vpc/outputs.tf
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モジュール

modules/security_group/security-group.tf
## 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"
  }
}
modules/security_group/variables.tf
variable "config" {
  type = object({
    vpc_id      = string
 })
}
modules/security_group/outputs.tf
output "security_group_id" {
  value = aws_security_group.example_SG.id
}

EC2モジュール

modules/ec2/ec2.tf
##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
}
modules/ec2/variables.tf
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モジュール

modules/alb/alb.tf
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 = ["*"]
    }
  }
}
modules/alb/variables.tf
variable "config" {
  type = object({
    vpc_id = string
    subnet-a_id = string
    subnet-c_id = string
    security_group_id = string
  })
}
modules/alb/outputs.tf
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

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

playbook.yml
- hosts: nginx
  become: true

  vars_files:
    - ./nginx/vars/main.yml
  roles:
    - nginx

Nginx Role

nginx/tasks/main.yml
- 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
nginx/vars/main.yml
# 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

参考文献

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0