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

Создание 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
Автор
Редакция

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

Как вести прямую трансляцию на YouTube
Стриминг

Как вести прямую трансляцию на YouTube

Перенос сообщений на новый iPhone
iPhone

Перенос сообщений на новый iPhone

3D-печать посуды: как сделать безопасно
3D‑п печать

3D-печать посуды: как сделать безопасно

Fortnite не запускается в Windows 11/10 — решения
Игры

Fortnite не запускается в Windows 11/10 — решения

Импорт музыки в Apple Music с Mac и Windows
How-to

Импорт музыки в Apple Music с Mac и Windows

Как создать и применять пресеты в Adobe Lightroom
Photo Editing

Как создать и применять пресеты в Adobe Lightroom