AWS VPC с Terraform

ToC

  1. Packer от Hashicorp
  2. Terraform для AWS
  3. AWS VPC с Terraform
  4. AWS EC2 с Terraform
  5. AWS ELB с Terraform

Что такое VPC

Amazon Virtual Private Cloud (Amazon VPC) – это логически изолированный раздел облака AWS, в котором можно запускать ресурсы AWS в созданной пользователем виртуальной сети. Пользователь полностью контролирует свою среду виртуальной сети, в том числе может выбирать собственный диапазон IP-адресов, создавать подсети, а также настраивать таблицы маршрутизации и сетевые шлюзы. Для обеспечения удобного и безопасного доступа к ресурсам и приложениям в VPC можно использовать как IPv4, так и IPv6.

Настройка

Приступим к конфигурации VPC.

В файл variables.tf добавляем блоки IP адресов, которые мы будем использовать внутри нашей VPC:

variable "vpc_cidr" {
    description = "CIDR for the whole VPC"
    default = "172.20.0.0/16"
}

variable "vpc_cidr_public" {
    description = "CIDR for the Public subnet"
    default = "172.20.0.0/24"
}

variable "vpc_cidr_private" {
    description = "CIDR for the Private subnet"
    default = "172.20.1.0/24"
}

Создаем файл vpc.tf с содержимым:

resource "aws_vpc" "MyVPC" {
    cidr_block           = "${var.vpc_cidr}"
    enable_dns_hostnames = true
    tags {
        Name        = "TF:VPC",
        Owner       = "owner@example.com",
        Environment = "Production",
        Description = "Custom VPC"
    }
}

В cidr_block мы указываем переменную из variables.tf vpc_cidr. Ну и тэги - очень удобный инструмент для работы и выборки через АПИ нужных ресурсов.

Теперь нам необходимо описать конфигурацию сети и доступ в интернет из нашего VPC.

Сеть

Добавляем в vpc.tf:

## Public subnet

resource "aws_subnet" "aws-subnet-public" {
  vpc_id            = "${aws_vpc.MyVPC.id}"
  cidr_block        = "${var.vpc_cidr_public}"
  availability_zone = "${var.aws_region}a"
  tags = {
    Name            = "Public subnet"
  }
}

## Private subnet

resource "aws_subnet" "aws-subnet-private" {
  vpc_id            = "${aws_vpc.MyVPC.id}"
  cidr_block        = "${var.vpc_cidr_private}"
  availability_zone = "${var.aws_region}b"
  tags = {
    Name            = "Private subnet"
  }
}

Тут переменных немного больше, но они практически все понятны. Опишу не самые очевидные вещи:

После этого можно применить изменения и посмотреть, что будет:

$ terraform apply -var-file=terraform.tfvars

Гейт в большой Интернет

Добавляем в vpc.tf:

## Internet gateway
resource "aws_internet_gateway" "gateway" {
    vpc_id = "${aws_vpc.MyVPC.id}"
}


## Elastic IP for NAT GW
resource "aws_eip" "eip" {
  vpc        = true
  depends_on = ["aws_internet_gateway.gateway"]
}


## NAT gateway
resource "aws_nat_gateway" "gateway" {
    allocation_id = "${aws_eip.eip.id}"
    subnet_id     = "${aws_subnet.aws-subnet-public.id}"
    depends_on    = ["aws_internet_gateway.gateway"]
}

output "NAT_GW_IP" {
  value = "${aws_eip.eip.public_ip}"
}

Итак, что тут происходит. Пройдем по блокам.

Почти закончили. Остается настроить таблицы маршрутизации.

Роутинг

Здесь будет немного сложнее понять, но я надеюсь, что вы разберетесь.

Создаем файл routing.tf с такими блоками:

## Default route to Internet

resource "aws_route" "internet_access" {
  route_table_id         = "${aws_vpc.MyVPC.main_route_table_id}"
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = "${aws_internet_gateway.gateway.id}"
}

## Routing table

resource "aws_route_table" "private_route_table" {
    vpc_id   = "${aws_vpc.MyVPC.id}"

    tags {
        Name = "Private route table"
    }
}

resource "aws_route" "private_route" {
    route_table_id  = "${aws_route_table.private_route_table.id}"
    destination_cidr_block = "0.0.0.0/0"
    nat_gateway_id = "${aws_nat_gateway.gateway.id}"
}

resource "aws_route_table" "public" {
  vpc_id = "${aws_vpc.MyVPC.id}"
  tags {
      Name = "Public route table"
  }
  route {
        cidr_block = "0.0.0.0/0"
        gateway_id = "${aws_internet_gateway.gateway.id}"
    }
}


## Route tables associations

# Associate subnet public_subnet to public route table
resource "aws_route_table_association" "public_subnet_association" {
    subnet_id = "${aws_subnet.aws-subnet-public.id}"
    route_table_id = "${aws_vpc.MyVPC.main_route_table_id}"
}

# Associate subnet private_subnet to private route table
resource "aws_route_table_association" "private_subnet_association" {
    subnet_id = "${aws_subnet.aws-subnet-private.id}"
    route_table_id = "${aws_route_table.private_route_table.id}"
}

Я предупреждал, что тут немного более запутано, но те, кто хорошо знает сети и маршрутизацию - легко заметит, что сначала мы создаем маршрут по умолчанию в таблице маршрутизации по умолчанию.

Дальше мы создаем внутреннюю таблицу маршрутизации и маршруты для приватной и публичной частей сети.

И наконец мы делаем привязку подсетей и таблиц маршрутизации.

Мой вам совет - перечитайте и нарисуйте связи на листе бумаги. Так будет проще понять. Расписывать подробно я тут не буду, оставлю это вам для домашнего задания.

Применяем, как мы делали это раньше.

Чтоб уничтожить все созданные ресурсы надо сделать destroy:

$ terraform destroy -var-file=terraform.tfvars

Исходники, как всегда, на GitHub.


Comments !