Customizable VPCs with CloudFormation Conditions

Using CloudFormation Conditions you can decide which resources to create/configure from your CloudFormation template.

In this post, we are going to build a template that can create a VPC with private subnets and a NAT gateway or only public subnets d…


This content originally appeared on DEV Community and was authored by Mawuli Denteh

Using CloudFormation Conditions you can decide which resources to create/configure from your CloudFormation template.

In this post, we are going to build a template that can create a VPC with private subnets and a NAT gateway or only public subnets depending on a parameter when creating the CloudFormation stack.

Steps to create and use Conditions

  1. Define the input parameters you want your condition to evaluate.
  2. Define the condition by using the intrinsic condition functions.
  3. Declare the condition in resources or outputs you want to create.

Let's dive into the example!

Define the parameter and condition

In the first part of our template, we'll define our parameter and condition.

We associate the CreatePrivateResources condition with a value/option from our CreateNatGateway parameter. This enables us to do what has been discussed in the intro above.

Parameters:
  CreateNatGateway:
    Type: String
    Description: "Need a NAT Gateway?"
    AllowedValues:
      - yes
      - no
    Default: yes

Conditions:
  CreatePrivateResources: !Equals
    - !Ref CreateNatGateway
    - yes

Define the public resources

Here, we will define our VPC, internet gateway, public subnets, routes and route tables. These resources will always be created. This is because they will not have any condition associated with them.

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: "10.0.0.0/16"
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-VPC"

  # Public Resources
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-InternetGateway"

  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.1.0/24"
      MapPublicIpOnLaunch: true
      AvailabilityZone: !Select [0, !GetAZs ""]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PublicSubnet1"

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.2.0/24"
      MapPublicIpOnLaunch: true
      AvailabilityZone: !Select [1, !GetAZs ""]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PublicSubnet2"

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PublicRouteTable"

  PublicRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

Use the condition

We now apply our condition to selected resources which creates a private environment for us, i.e. NatGateway, private subnets and routes etc. If we choose no at the prompt, these will not get created.

We also control the display of outputs using the same conditions.

# Private Resources
  NatGateway:
    Condition: CreatePrivateResources
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt EIPNatGateway.AllocationId
      SubnetId: !Ref PublicSubnet1
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-NatGateway"

  EIPNatGateway:
    Condition: CreatePrivateResources
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-EIPNatGateway"

  PrivateSubnet1:
    Condition: CreatePrivateResources
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.3.0/24"
      MapPublicIpOnLaunch: false
      AvailabilityZone: !Select [0, !GetAZs ""]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PrivateSubnet1"

  PrivateSubnet2:
    Condition: CreatePrivateResources
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.4.0/24"
      MapPublicIpOnLaunch: false
      AvailabilityZone: !Select [1, !GetAZs ""]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PrivateSubnet2"

  PrivateRouteTable:
    Condition: CreatePrivateResources
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PrivateRouteTable"

  PrivateRoute:
    Condition: CreatePrivateResources
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationCidrBlock: "0.0.0.0/0"
      NatGatewayId: !Ref NatGateway

  PrivateSubnet1RouteTableAssociation:
    Condition: CreatePrivateResources
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnet2RouteTableAssociation:
    Condition: CreatePrivateResources
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateRouteTable

Outputs:
  VPCId:
    Description: "VPC ID"
    Value: !Ref VPC
  PublicSubnet1Id:
    Description: "Public Subnet 1 ID"
    Value: !Ref PublicSubnet1
  PublicSubnet2Id:
    Description: "Public Subnet 2 ID"
    Value: !Ref PublicSubnet2
  PrivateSubnet1Id:
    Condition: CreatePrivateResources
    Description: "Private Subnet 1 ID"
    Value: !Ref PrivateSubnet1
  PrivateSubnet2Id:
    Condition: CreatePrivateResources
    Description: "Private Subnet 2 ID"
    Value: !Ref PrivateSubnet2
  NatGatewayId:
    Condition: CreatePrivateResources
    Description: "NAT Gateway ID"
    Value: !Ref NatGateway

You can now customize your VPC creation just by changing a parameter.
Thanks for reading. Happy Building!


This content originally appeared on DEV Community and was authored by Mawuli Denteh


Print Share Comment Cite Upload Translate Updates
APA

Mawuli Denteh | Sciencx (2025-01-13T03:29:22+00:00) Customizable VPCs with CloudFormation Conditions. Retrieved from https://www.scien.cx/2025/01/13/customizable-vpcs-with-cloudformation-conditions/

MLA
" » Customizable VPCs with CloudFormation Conditions." Mawuli Denteh | Sciencx - Monday January 13, 2025, https://www.scien.cx/2025/01/13/customizable-vpcs-with-cloudformation-conditions/
HARVARD
Mawuli Denteh | Sciencx Monday January 13, 2025 » Customizable VPCs with CloudFormation Conditions., viewed ,<https://www.scien.cx/2025/01/13/customizable-vpcs-with-cloudformation-conditions/>
VANCOUVER
Mawuli Denteh | Sciencx - » Customizable VPCs with CloudFormation Conditions. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/01/13/customizable-vpcs-with-cloudformation-conditions/
CHICAGO
" » Customizable VPCs with CloudFormation Conditions." Mawuli Denteh | Sciencx - Accessed . https://www.scien.cx/2025/01/13/customizable-vpcs-with-cloudformation-conditions/
IEEE
" » Customizable VPCs with CloudFormation Conditions." Mawuli Denteh | Sciencx [Online]. Available: https://www.scien.cx/2025/01/13/customizable-vpcs-with-cloudformation-conditions/. [Accessed: ]
rf:citation
» Customizable VPCs with CloudFormation Conditions | Mawuli Denteh | Sciencx | https://www.scien.cx/2025/01/13/customizable-vpcs-with-cloudformation-conditions/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.