Гид по технологиям

Создание VPC с CloudFormation: 2 публичных и 2 приватных подсети

5 min read AWS CloudFormation Обновлено 30 Oct 2025
VPC в CloudFormation: 2 публичных и 2 приватных подсети
VPC в CloudFormation: 2 публичных и 2 приватных подсети

В этой статье показано, как подготовить шаблон CloudFormation и развернуть стек, который создаёт VPC с подсетями, маршрутными таблицами, Интернет-шлюзом и NAT-шлюзами. Внимание: исходный шаблон в этом руководстве создаёт по три публичные и приватные подсети; в тексте уточнено отличие от заголовка и предлагаются варианты для двух подсетей.

Введение

CloudFormation позволяет описывать и управлять ресурсами AWS текстовым шаблоном в формате YAML или JSON. Шаблон обеспечивает воспроизводимость инфраструктуры, уменьшает ручные операции и делает процессы единообразными.

Короткое определение: шаблон — это файл YAML/JSON, который описывает ресурсы AWS и их связи.

Предварительные требования

  1. Учетная запись AWS (создайте, если ещё нет).
  2. Базовое понимание шаблонов CloudFormation.

Что мы сделаем

  1. Войдём в AWS Console.
  2. Подготовим шаблон CloudFormation.
  3. Создадим стек CloudFormation и проверим ресурсы.

Вход в AWS

  1. Перейдите на страницу входа в AWS.

Когда вы откроете страницу входа, введите свои учётные данные.

Вход в AWS

После успешного входа вы увидите консоль с перечнем сервисов.

Консоль управления AWS

Создание шаблона

Ниже приведён пример шаблона. Скопируйте его и сохраните локально. Обратите внимание: в самом шаблоне заданы 3 публичные и 3 приватные подсети — это важно для понимания результатов развертывания.

---  
AWSTemplateFormatVersion: 2010-09-09  
Description: >  
  This Templates creates a VPC with 3 public and 3 private subnets.  
Parameters:  
  VpcCIDR:  
    Type: String  
    Description: VPC CIDR (Do Not Change if no customization is required).   
    Default: 10.10.0.0/16  
  PrivateAZ1SubnetCIDR:  
    Type: String  
    Description: Subnet CIDR for 1st Availability Zone (Do Not Change if no customization is required).  
    Default: 10.10.80.0/21  
  PrivateAZ2SubnetCIDR:  
    Type: String  
    Description: Subnet CIDR for 2nd Availability Zone (Do Not Change if no customization is required).  
    Default: 10.10.88.0/21  
  PrivateAZ3SubnetCIDR:  
    Type: String  
    Description: Subnet CIDR for 3rd Availability Zone (Do Not Change if no customization is required).  
    Default: 10.10.96.0/21  
  PublicAZ1SubnetCIDR:  
    Type: String  
    Description: Subnet CIDR for 1st Availability Zone (Do Not Change if no customization is required).  
    Default: 10.10.0.0/21  
  PublicAZ2SubnetCIDR:  
    Type: String  
    Description: Subnet CIDR for 2nd Availability Zone (Do Not Change if no customization is required).  
    Default: 10.10.8.0/21  
  PublicAZ3SubnetCIDR:  
    Type: String  
    Description: Subnet CIDR for 3rd Availability Zone (Do Not Change if no customization is required).   
    Default: 10.10.16.0/21  
Metadata:  
  AWS::CloudFormation::Interface:  
    ParameterGroups:  
      - Label:  
          default: VPC  
        Parameters:  
          - VpcCIDR  
      - Label:  
          default: Availabilty Zone 1  
        Parameters:  
          - PublicAZ1SubnetCIDR  
          - PrivateAZ1SubnetCIDR  
      - Label:  
          default: Availabilty Zone 1  
        Parameters:  
          - PublicAZ2SubnetCIDR  
          - PrivateAZ2SubnetCIDR  
      - Label:  
          default: Availabilty Zone 1  
        Parameters:  
          - PublicAZ3SubnetCIDR  
          - PrivateAZ3SubnetCIDR  
Resources:  
  Vpc:  
    Type: AWS::EC2::VPC  
    Properties:  
      CidrBlock: !Ref VpcCIDR  
      Tags:  
        - Key: Name  
          Value: !Sub ${AWS::StackName}  
  InternetGateway:  
    Type: AWS::EC2::InternetGateway  
    Properties:  
      Tags:  
        - Key: Name  
          Value: !Sub ${AWS::StackName}  
  VPCGatewayAttachment:  
    Type: AWS::EC2::VPCGatewayAttachment  
    Properties:  
      InternetGatewayId: !Ref InternetGateway  
      VpcId: !Ref Vpc  
  # Public Subnets - Route Table  
  PublicRouteTable:  
    Type: AWS::EC2::RouteTable  
    Properties:  
      VpcId: !Ref Vpc  
      Tags:  
        - Key: Name  
          Value: !Sub ${AWS::StackName}-public  
        - Key: Type  
          Value: public  
  PublicSubnetsRoute:  
    Type: AWS::EC2::Route  
    Properties:  
      RouteTableId: !Ref PublicRouteTable  
      DestinationCidrBlock: 0.0.0.0/0  
      GatewayId: !Ref InternetGateway  
    DependsOn: VPCGatewayAttachment  
  # Public Subnets  
  PublicAZ1Subnet:  
    Type: AWS::EC2::Subnet  
    Properties:  
      VpcId: !Ref Vpc  
      CidrBlock: !Ref PublicAZ1SubnetCIDR  
      AvailabilityZone: !Select [0, !GetAZs ""]  
      MapPublicIpOnLaunch: true  
      Tags:  
        - Key: Name  
          Value: !Sub  
            - ${AWS::StackName}-public-${AZ}  
            - { AZ: !Select [0, !GetAZs ""] }  
        - Key: Type  
          Value: public  
  PublicAZ1SubnetRouteTableAssociation:  
    Type: AWS::EC2::SubnetRouteTableAssociation  
    Properties:  
      SubnetId: !Ref PublicAZ1Subnet  
      RouteTableId: !Ref PublicRouteTable  
  PublicAZ2Subnet:  
    Type: AWS::EC2::Subnet  
    Properties:  
      VpcId: !Ref Vpc  
      CidrBlock: !Ref PublicAZ2SubnetCIDR  
      AvailabilityZone: !Select [1, !GetAZs ""]  
      MapPublicIpOnLaunch: true  
      Tags:  
        - Key: Name  
          Value: !Sub  
            - ${AWS::StackName}-public-${AZ}  
            - { AZ: !Select [1, !GetAZs ""] }  
        - Key: Type  
          Value: public  
  PublicAZ2SubnetRouteTableAssociation:  
    Type: AWS::EC2::SubnetRouteTableAssociation  
    Properties:  
      SubnetId: !Ref PublicAZ2Subnet  
      RouteTableId: !Ref PublicRouteTable  
  PublicAZ3Subnet:  
    Type: AWS::EC2::Subnet  
    Properties:  
      VpcId: !Ref Vpc  
      CidrBlock: !Ref PublicAZ3SubnetCIDR  
      AvailabilityZone: !Select [2, !GetAZs ""]  
      MapPublicIpOnLaunch: true  
      Tags:  
        - Key: Name  
          Value: !Sub  
            - ${AWS::StackName}-public-${AZ}  
            - { AZ: !Select [2, !GetAZs ""] }  
        - Key: Type  
          Value: public  
  PublicAZ3SubnetRouteTableAssociation:  
    Type: AWS::EC2::SubnetRouteTableAssociation  
    Properties:  
      SubnetId: !Ref PublicAZ3Subnet  
      RouteTableId: !Ref PublicRouteTable  
  # Private Subnets - NAT Gateways  
  AZ1NatGatewayEIP:  
    Type: AWS::EC2::EIP  
    Properties:  
      Domain: vpc  
    DependsOn: VPCGatewayAttachment  
  AZ1NatGateway:  
    Type: AWS::EC2::NatGateway  
    Properties:  
      AllocationId: !GetAtt AZ1NatGatewayEIP.AllocationId  
      SubnetId: !Ref PublicAZ1Subnet  
  AZ2NatGatewayEIP:  
    Type: AWS::EC2::EIP  
    Properties:  
      Domain: vpc  
    DependsOn: VPCGatewayAttachment  
  AZ2NatGateway:  
    Type: AWS::EC2::NatGateway  
    Properties:  
      AllocationId: !GetAtt AZ2NatGatewayEIP.AllocationId  
      SubnetId: !Ref PublicAZ2Subnet  
  AZ3NatGatewayEIP:  
    Type: AWS::EC2::EIP  
    Properties:  
      Domain: vpc  
    DependsOn: VPCGatewayAttachment  
  AZ3NatGateway:  
    Type: AWS::EC2::NatGateway  
    Properties:  
      AllocationId: !GetAtt AZ3NatGatewayEIP.AllocationId  
      SubnetId: !Ref PublicAZ3Subnet  
  # Private Subnets  
  PrivateAZ1Subnet:  
    Type: AWS::EC2::Subnet  
    Properties:  
      VpcId: !Ref Vpc  
      CidrBlock: !Ref PrivateAZ1SubnetCIDR  
      AvailabilityZone: !Select [0, !GetAZs ""]  
      Tags:  
        - Key: Name  
          Value: !Sub  
            - ${AWS::StackName}-private-${AZ}  
            - { AZ: !Select [0, !GetAZs ""] }  
        - Key: Type  
          Value: private  
  PrivateAZ1RouteTable:  
    Type: AWS::EC2::RouteTable  
    Properties:  
      VpcId: !Ref Vpc  
      Tags:  
        - Key: Name  
          Value: !Sub  
            - ${AWS::StackName}-private-${AZ}  
            - { AZ: !Select [0, !GetAZs ""] }  
        - Key: Type  
          Value: private  
  PrivateAZ1Route:  
    Type: AWS::EC2::Route  
    Properties:  
      RouteTableId: !Ref PrivateAZ1RouteTable  
      DestinationCidrBlock: 0.0.0.0/0  
      NatGatewayId: !Ref AZ1NatGateway  
  PrivateAZ1RouteTableAssociation:  
    Type: AWS::EC2::SubnetRouteTableAssociation  
    Properties:  
      SubnetId: !Ref PrivateAZ1Subnet  
      RouteTableId: !Ref PrivateAZ1RouteTable  
  PrivateAZ2Subnet:  
    Type: AWS::EC2::Subnet  
    Properties:  
      VpcId: !Ref Vpc  
      CidrBlock: !Ref PrivateAZ2SubnetCIDR  
      AvailabilityZone: !Select [1, !GetAZs ""]  
      Tags:  
        - Key: Name  
          Value: !Sub  
            - ${AWS::StackName}-private-${AZ}  
            - { AZ: !Select [1, !GetAZs ""] }  
        - Key: Type  
          Value: private  
  PrivateAZ2RouteTable:  
    Type: AWS::EC2::RouteTable  
    Properties:  
      VpcId: !Ref Vpc  
      Tags:  
        - Key: Name  
          Value: !Sub  
            - ${AWS::StackName}-private-${AZ}  
            - { AZ: !Select [1, !GetAZs ""] }  
        - Key: Type  
          Value: private  
  PrivateAZ2Route:  
    Type: AWS::EC2::Route  
    Properties:  
      RouteTableId: !Ref PrivateAZ2RouteTable  
      DestinationCidrBlock: 0.0.0.0/0  
      NatGatewayId: !Ref AZ2NatGateway  
  PrivateAZ2RouteTableAssociation:  
    Type: AWS::EC2::SubnetRouteTableAssociation  
    Properties:  
      SubnetId: !Ref PrivateAZ2Subnet  
      RouteTableId: !Ref PrivateAZ2RouteTable  
  PrivateAZ3Subnet:  
    Type: AWS::EC2::Subnet  
    Properties:  
      VpcId: !Ref Vpc  
      CidrBlock: !Ref PrivateAZ3SubnetCIDR  
      AvailabilityZone: !Select [2, !GetAZs ""]  
      Tags:  
        - Key: Name  
          Value: !Sub  
            - ${AWS::StackName}-private-${AZ}  
            - { AZ: !Select [2, !GetAZs ""] }  
        - Key: Type  
          Value: private  
  PrivateAZ3RouteTable:  
    Type: AWS::EC2::RouteTable  
    Properties:  
      VpcId: !Ref Vpc  
      Tags:  
        - Key: Name  
          Value: !Sub  
            - ${AWS::StackName}-private-${AZ}  
            - { AZ: !Select [2, !GetAZs ""] }  
        - Key: Type  
          Value: private  
  PrivateAZ3Route:  
    Type: AWS::EC2::Route  
    Properties:  
      RouteTableId: !Ref PrivateAZ3RouteTable  
      DestinationCidrBlock: 0.0.0.0/0  
      NatGatewayId: !Ref AZ3NatGateway  
  PrivateAZ3RouteTableAssociation:  
    Type: AWS::EC2::SubnetRouteTableAssociation  
    Properties:  
      SubnetId: !Ref PrivateAZ3Subnet  
      RouteTableId: !Ref PrivateAZ3RouteTable  
    
Outputs:  
  VpcId:  
    Description: VPC Id  
    Value: !Ref Vpc  
    Export:  
      Name: !Sub "${AWS::StackName}-VPC-ID"

Important

  • Несмотря на заголовок статьи, шаблон создаёт 3 публичные и 3 приватные подсети. Если вам нужны только 2 публичные и 2 приватные подсети, удалите из шаблона ресурсы, связанные с третьей AZ (PublicAZ3Subnet, AZ3NatGateway и т.д.), и скорректируйте параметры.

Создание стека CloudFormation

  1. В консоли AWS выберите Services и найдите CloudFormation.

CloudFormation

  1. На панели нажмите Create stack → With new resources (standard).

Создать стек

  1. Загрузите локальный файл шаблона: Template is ready → Upload a template file → Choose file → Next.

Загрузить шаблон

  1. Задайте имя стека, оставьте параметры по умолчанию или при необходимости измените CIDR блоки.

Имя стека и параметры

  1. При необходимости добавьте теги.

Теги

  1. Нажмите Create stack и дождитесь завершения. Развёртывание займёт несколько минут.

Процесс создания стека

Моя VPC

Вы можете отслеживать события в вкладке Events.

События стека

Перейдите в сервис VPC, чтобы увидеть созданные ресурсы (VPC, подсети, маршруты, Интернет-шлюз, NAT-шлюзы).

Панель VPC

Ресурсы VPC

Чтобы удалить все созданные ресурсы, просто удалите стек CloudFormation — все ресурсы, созданные через стек, будут удалены автоматически (если для них нет зависимостей вне стека).

Список стеков

Лучшие практики и советы

  • Версионируйте шаблоны в системе контроля версий (Git).
  • Тестируйте шаблон в отдельном тестовом аккаунте или в изолированной среде перед продом.
  • Используйте описательные теги (Environment, Owner, Project) для ресурсов.
  • Для высокодоступных решений распределяйте NAT-шлюзы по AZ или рассмотрите использование NAT-инстансов как альтернативы при ограниченном бюджете.
  • Сохраняйте аккуратную структуру параметров и делайте значения по умолчанию удобными для CI/CD.

Когда такой подход не подходит (контрпримеры)

  • Очень мелкие одноразовые эксперименты: проще создать ресурсы вручную.
  • Нужно управлять очень сложной логикой на время выполнения — для неё чаще используют AWS CDK или Terraform с модулями.
  • Если требуется мультиоблачная инфраструктура — выбирайте Terraform.

Альтернативные подходы

  • AWS CDK: инфраструктура на знакомом языке программирования (TypeScript, Python, Java).
  • Terraform: мультиоблачное управление ресурсами с модульной архитектурой.
  • Ручное создание в консоли: быстрый способ для разовых действий.

Стоимость и влияние

  • NAT Gateway тарифицируется отдельно и может существенно влиять на счёт при больших объёмах исходящего трафика. Если важна экономия, рассмотрите NAT-инстансы или централизованный NAT в отдельном AZ.
  • Интернет-шлюз сам по себе бесплатен, но ресурсы, к нему подключённые, генерируют стоимость.

Роли и чек-листы

Для разработчика/инженера, разворачивающего стек:

  • Проверить CIDR-планы и избежать пересечений.
  • Убедиться, что шаблон синтаксически корректен (aws cloudformation validate-template).
  • Тестировать в изолированной среде.

Для владельца проекта:

  • Убедиться, что заданы теги Billing/Owner/Environment.
  • Оценить стоимость NAT-шлюзов.

Мини-методология тестирования

  1. validate-template — проверка синтаксиса.
  2. Развёртывание в тестовом аккаунте с префиксом test-.
  3. Проверка созданных ресурсов через консоль и CLI (aws ec2 describe-vpcs, describe-subnets).
  4. Удаление стека и проверка отчистки ресурсов.

Критерии приёмки

  • Стек завершил создание без ошибок.
  • Созданный VPC имеет ожидаемый CIDR.
  • Количество подсетей соответствует обновлённому шаблону (2 или 3 в зависимости от правок).
  • Публичные подсети имеют MapPublicIpOnLaunch: true.

Безопасность и соответствие

  • Ограничьте доступ к CloudFormation и правам на создание сетевых ресурсов через IAM-политики.
  • Не храните чувствительные данные в шаблоне; используйте Parameter Store/Secrets Manager.

Краткий глоссарий (1 строка)

  • VPC — виртуальная приватная сеть в AWS; CIDR — сетевой диапазон; NAT Gateway — сервис для исходящего доступа приватных подсетей.

Часто задаваемые вопросы

Q: Почему в шаблоне 3 подсети, если заголовок говорит про 2?

A: Шаблон, включённый в эту статью, создаёт 3 публичные и 3 приватные подсети. Если нужен вариант с двумя подсетями, удалите ресурсы для третьей зоны Availability Zone из шаблона.

Q: Как удалить все ресурсы, созданные этим шаблоном?

A: Удалите стек CloudFormation — ресурсы, связанные со стеком, будут удалены автоматически, если нет внешних зависимостей.

Q: Можно ли избежать затрат на NAT Gateway?

A: Да — использовать NAT-инстансы, централизованный NAT или proxy в зависимости от нагрузки и требований к отказоустойчивости.

Заключение

Мы рассмотрели, как подготовить и развернуть шаблон CloudFormation, который создаёт VPC с подсетями, маршрутами, Интернет- и NAT-шлюзами. Обратите внимание на несоответствие между заголовком и шаблоном и выберите нужную вам конфигурацию (2 или 3 AZ). Следуйте лучшим практикам: тестируйте шаблоны, версионируйте, отслеживайте стоимость и применяйте IAM для контроля доступа.

Короткое объявление

Это руководство показывает шаги для создания сети AWS с помощью CloudFormation: подготовка шаблона, загрузка в консоль и создание стека. Подходит для быстрой автоматизации сетевой инфраструктуры и повторяемого развёртывания.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Троян Herodotus: как он работает и как защититься
Кибербезопасность

Троян Herodotus: как он работает и как защититься

Включить новое меню «Пуск» в Windows 11
Windows 11

Включить новое меню «Пуск» в Windows 11

Панель полей PivotTable в Excel — руководство
Excel

Панель полей PivotTable в Excel — руководство

Включить новый Пуск в Windows 11 — инструкция
Windows

Включить новый Пуск в Windows 11 — инструкция

Как убрать дубликаты Диспетчера задач Windows 11
Windows

Как убрать дубликаты Диспетчера задач Windows 11

Как просмотреть историю просмотров Reels в Instagram
Социальные сети

Как просмотреть историю просмотров Reels в Instagram