Сетевое взаимодействие в AWS (версия Terraform)

Ранее на этой неделе я создал пост, в котором подробно описал, как создать хорошо спроектированный vpc в AWS. Я решил вернуться к этой теме и поговорить о том, как это реализовать в реальном проекте.

Если вы работаете с AWS для своего работодателя или для личных нужд, у вас, вероятно, есть несколько ресурсов, которые вы создаете и используете в различных сервисах AWS. Отслеживание того, из чего состоит ваш стек, может надоесть, если все, на что вы можете ориентироваться, — это ваша собственная память или документ с некоторым списком ресурсов. Именно здесь на помощь приходит инфраструктура как код. Идея заключается в том, что у вас есть шаблон определенной формы, который развертывает для вас необходимый стек. Затем вы можете развернуть несколько экземпляров этого шаблона для использования в качестве различных сред, просто передавая различные входные параметры. Это становится стандартным процессом управления программными проектами, поскольку инженеры пишут код приложения, а затем также пишут шаблон, описывающий инфраструктуру, на которой будет работать их код.

В этой заметке я расскажу вам о том, как я делал это ранее, но с использованием Terraform для всей инфраструктуры. Я не буду рассказывать о том, что такое Terraform (по крайней мере, не в этом посте) или как настроить провайдера AWS. Я буду описывать только создание сети, как в моем другом посте.

В этом шаблоне я использую одну из самых необычных функций Terraform, cidrsubnet. Это ОЧЕНЬ полезная функция, и я рекомендую ознакомиться с ней. Вкратце, первый аргумент — это cidr вашего VPC, второй — подсеть, для которой вы пытаетесь получить блок cidr, а третий — количество бит, которые вы добавляете к маске подсети.

# For this example we will assume that the value being given to this variable is ["Public", "Private", "Isolated"]
variable "subnet_names" {
  type = list(string)
}

# Create the VPC.
resource "aws_vpc" "this" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "MyVpc"
  }
}

# Adopt the default route table into our terraform state
resource "aws_default_route_table" "this" {
  default_route_table_id = aws_vpc.this.default_route_table_id

  tags = {
    Name = "Unused"
  }
}

# Adopt the default network ACL into our terraform state
resource "aws_default_network_acl" "this" {
  default_network_acl_id = aws_vpc.this.default_network_acl_id

  # By adding no rules this resource defaults to deny all

  tags = {
    Name = "Unused"
  }
}

# Create our Public, Private and Isolated subnets
resource "aws_subnet" "this" {
  count = length(var.subnet_names)

  vpc_id     = aws_vpc.this.id
  cidr_block = cidrsubnet("10.0.0.0/16", count.index, 2)

  tags = {
    Name = var.subnet_names[count.index]
  }
}

# Create a route table for each of our subnets
resource "aws_route_table" "this" {
  count = length(var.subnet_names)

  vpc_id = aws_vpc.this.id

  tags = {
    Name = var.subnet_names[count.index]
  }
}

# Associate our route tables with the appropriate subnets
resource "aws_route_table_association" "this"
  count = length(var.subnet_names)

  route_table_id = aws_route_table.this[count.index]
  subnet_id      = aws_subnet.this[count.index]
}

# Create the internet gateway
resource "aws_internet_gateway" "this" {
  vpc_id = aws_vpc.this.id

  tags = {
    Name = "InternetGateway"
  }
}

# Create the Elastic IP
resource "aws_eip" "this" {
  vpc = true

  tags = {
    Name = "My Elastic IP"
  }
}

# Create the NAT Gateway
resource "aws_nat_gateway" "this" {
  allocation_id     = aws_eip.this.id
  subnet            = aws_subnet.this[0].id
  connectivity_type = "public"

  tags = {
    Name = "NAT Gateway"
  }
}

# Create our Public subnet route
resource "aws_route" "public" {
  route_table_id         = aws_route_table.this[0].id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.this.id
}

# Create our Private subnet route
resource "aws_route" "private" {
  route_table_id         = aws_route_table.this[1].id
  destination_cidr_block = "0.0.0.0/0"
  nat_gateway_id         = aws_nat_gateway.this.id
}

# Create our Network ACLs
resource "aws_network_acl" "this" {
  count = length(var.subnet_names)

  vpc_id = aws_vpc.this.id

  tags = {
    Name = var.subnet_names[count.index]
  }
}

# Associate each ACL with its subnet
resource "aws_network_acl_association" "this" {
  count = length(var.subnet_names)

  network_acl_id = aws_network_acl.this[count.index].id
  subnet_id      = aws_subnet.this[count.index].id
}

# Create the ACL rule for our Public subnet
resource "aws_network_acl_rule" "public" {
  network_acl_id = aws_network_acl.this[0].id
  rule_number    = 100
  rule_action    = "allow"
  protocol       = "tcp"
  to_port        = 443
  from_port      = 443
  cidr_block     = "0.0.0.0/0"
}

# Create the ACL rule for our Private subnet
resource "aws_network_acl_rule" "private" {
  network_acl_id = aws_network_acl.this[1].id
  rule_number    = 100
  rule_action    = "allow"
  protocol       = "tcp"
  to_port        = 1024
  from_port      = 65535
  cidr_block     = aws_vpc.this.cidr_block
}

# Create the ACL rule for our Isolated subnet
resource "aws_network_acl_rule" "isolated" {
  network_acl_id = aws_network_acl.this[2].id
  rule_number    = 100
  rule_action    = "allow"
  protocol       = "tcp"
  to_port        = 5432
  from_port      = 5432
  cidr_block     = aws_vpc.this.cidr_block
}
Вход в полноэкранный режим Выход из полноэкранного режима

Оцените статью
devanswers.ru
Добавить комментарий