Search code examples
amazon-web-servicesaws-cloudformationamazon-elbamazon-vpcnested-stack

Referencing the output of Parent stack in nested stack - Cloudformation


I am trying to create the nested stack but having trouble as I am new to this and still in learning process. I have created the vpc with 2 private and 2 public subnets. Then attached the internet-facing elb to 2 public subnets. I think I am not referencing it right. Vpc is created but while creating elb there is an error Output 'VpcID' not found in stack I think there might be a problem in the syntax as I am changing my previous file to nested stack. I might not be referencing right in the Internet facing elb stack.

Root stack:

---
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  bucketname:
    Type: String
    Description: Path to the bucket
    Default: wahaj-webserver
  bucketpath:
    Type: String
    Description: Path to the bucket
    Default: /nested-stack
Resources:
  Vpcstack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: !Sub "https://${bucketname}.s3.us-east-2.amazonaws.com${bucketpath}/vpc1.yml"

  elb:
    DependsOn: Vpcstack
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: !Sub "https://${bucketname}.s3.us-east-2.amazonaws.com${bucketpath}/internetfacing-elb.yml"
      Parameters:
        SubnetA: !GetAtt Vpcstack.Outputs.SubnetA
        SubnetB: !GetAtt Vpcstack.Outputs.SubnetB
        VpcID: !GetAtt Vpcstack.Outputs.VpcID

Vpc stack:

---
AWSTemplateFormatVersion: 2010-09-09
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 11.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      InstanceTenancy: default
  InternetGateway:
    Type: AWS::EC2::InternetGateway
  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway
  SubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: us-east-2a
      VpcId: !Ref VPC
      CidrBlock: 11.0.0.0/24
      MapPublicIpOnLaunch: true
  SubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: us-east-2b
      VpcId: !Ref VPC
      CidrBlock: 11.0.1.0/24
      MapPublicIpOnLaunch: true
  SubnetC:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: us-east-2a
      VpcId: !Ref VPC
      CidrBlock: 11.0.2.0/24
      MapPublicIpOnLaunch: false
  SubnetD:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: us-east-2b
      VpcId: !Ref VPC
      CidrBlock: 11.0.3.0/24
      MapPublicIpOnLaunch: false
  RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
  RouteTable2:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
  InternetRoute:
    Type: AWS::EC2::Route
    DependsOn: VPCGatewayAttachment
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
      RouteTableId: !Ref RouteTable
  SubnetARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTable
      SubnetId: !Ref SubnetA
  SubnetBRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTable
      SubnetId: !Ref SubnetB
  SubnetCRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTable2
      SubnetId: !Ref SubnetC

  SubnetDRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTable2
      SubnetId: !Ref SubnetD
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: "Internet Group"
      GroupDescription: "SSH traffic in, all traffic out."
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: "22"
          ToPort: "22"
          CidrIp: 0.0.0.0/0
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
  NAT:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId:
        Fn::GetAtt:
          - EIP
          - AllocationId
      SubnetId:
        Ref: SubnetA
      Tags:
        - Key: Name
          Value: wahaj-nat
  EIP:
    DependsOn: VPCGatewayAttachment
    Type: AWS::EC2::EIP
    Properties:
      Domain: VPC
  Route:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId:
        Ref: RouteTable2
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId:
        Ref: NAT
Outputs:
  VpcID:
    Description: VPC id
    Value: !Ref VPC
    Export:
      Name: "VpcID"
  SubnetA:
    Description: public subnet
    Value: !Ref SubnetA
    Export:
      Name: "SubnetA"
  SubnetB:
    Description: public subnet 2
    Value: !Ref SubnetB
    Export:
      Name: "SubnetB"
  SubnetC:
    Description: priavte subnet
    Value: !Ref SubnetC
    Export:
      Name: "SubnetC"
  SubnetD:
    Description: private subnet 2
    Value: !Ref SubnetD
    Export:
      Name: "SubnetD"

Internet facing elb:

---
AWSTemplateFormatVersion: 2010-09-09
Resources:
  wahajelb:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: wahaj-elb
      VpcId:
        Fn::ImportValue: "VpcID"
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
          Description: For traffic from Internet
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
          Description: For traffic from Internet
      GroupDescription: Security Group for demo server

  MyLoadBalancer:
    Type: AWS::ElasticLoadBalancing::LoadBalancer
    Properties:
      Listeners:
        - LoadBalancerPort: "80"
          InstancePort: "80"
          Protocol: HTTP
      SecurityGroups:
        - !Ref wahajelb
      LoadBalancerName: wahajelb
      Subnets:
        - Fn::ImportValue: "SubnetA"
        - Fn::ImportValue: "SubnetB"
      HealthCheck:
        Target: HTTP:80/SamplePage.php
        HealthyThreshold: "3"
        UnhealthyThreshold: "5"
        Interval: "30"
        Timeout: "5"
Outputs:
  ec2:
    Description: ec2
    Value: !Ref MyLoadBalancer
    Export:
      Name: "MyLoadBalancer"
  lgsg:
    Description: lg-sg
    Value: !GetAtt wahajelb.GroupId
    Export:
      Name: "lgsg"


Solution

  • Your Vpc stack has an out out of vpcID not VpcID.

    This must be an exact string match for it to be successfully referenced in your Root stack

    Update your Vpc stack to the below

    ---
    AWSTemplateFormatVersion: 2010-09-09
    Resources:
      VPC:
        Type: AWS::EC2::VPC
        Properties:
          CidrBlock: 11.0.0.0/16
          EnableDnsSupport: true
          EnableDnsHostnames: true
          InstanceTenancy: default
      InternetGateway:
        Type: AWS::EC2::InternetGateway
      VPCGatewayAttachment:
        Type: AWS::EC2::VPCGatewayAttachment
        Properties:
          VpcId: !Ref VPC
          InternetGatewayId: !Ref InternetGateway
      SubnetA:
        Type: AWS::EC2::Subnet
        Properties:
          AvailabilityZone: us-east-2a
          VpcId: !Ref VPC
          CidrBlock: 11.0.0.0/24
          MapPublicIpOnLaunch: true
      SubnetB:
        Type: AWS::EC2::Subnet
        Properties:
          AvailabilityZone: us-east-2b
          VpcId: !Ref VPC
          CidrBlock: 11.0.1.0/24
          MapPublicIpOnLaunch: true
      SubnetC:
        Type: AWS::EC2::Subnet
        Properties:
          AvailabilityZone: us-east-2a
          VpcId: !Ref VPC
          CidrBlock: 11.0.2.0/24
          MapPublicIpOnLaunch: false
      SubnetD:
        Type: AWS::EC2::Subnet
        Properties:
          AvailabilityZone: us-east-2b
          VpcId: !Ref VPC
          CidrBlock: 11.0.3.0/24
          MapPublicIpOnLaunch: false
      RouteTable:
        Type: AWS::EC2::RouteTable
        Properties:
          VpcId: !Ref VPC
      RouteTable2:
        Type: AWS::EC2::RouteTable
        Properties:
          VpcId: !Ref VPC
      InternetRoute:
        Type: AWS::EC2::Route
        DependsOn: VPCGatewayAttachment
        Properties:
          DestinationCidrBlock: 0.0.0.0/0
          GatewayId: !Ref InternetGateway
          RouteTableId: !Ref RouteTable
      SubnetARouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
          RouteTableId: !Ref RouteTable
          SubnetId: !Ref SubnetA
      SubnetBRouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
          RouteTableId: !Ref RouteTable
          SubnetId: !Ref SubnetB
      SubnetCRouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
          RouteTableId: !Ref RouteTable2
          SubnetId: !Ref SubnetC
    
      SubnetDRouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
          RouteTableId: !Ref RouteTable2
          SubnetId: !Ref SubnetD
      SecurityGroup:
        Type: AWS::EC2::SecurityGroup
        Properties:
          GroupName: "Internet Group"
          GroupDescription: "SSH traffic in, all traffic out."
          VpcId: !Ref VPC
          SecurityGroupIngress:
            - IpProtocol: tcp
              FromPort: "22"
              ToPort: "22"
              CidrIp: 0.0.0.0/0
          SecurityGroupEgress:
            - IpProtocol: -1
              CidrIp: 0.0.0.0/0
      NAT:
        Type: AWS::EC2::NatGateway
        Properties:
          AllocationId:
            Fn::GetAtt:
              - EIP
              - AllocationId
          SubnetId:
            Ref: SubnetA
          Tags:
            - Key: Name
              Value: wahaj-nat
      EIP:
        DependsOn: VPCGatewayAttachment
        Type: AWS::EC2::EIP
        Properties:
          Domain: VPC
      Route:
        Type: AWS::EC2::Route
        Properties:
          RouteTableId:
            Ref: RouteTable2
          DestinationCidrBlock: 0.0.0.0/0
          NatGatewayId:
            Ref: NAT
    Outputs:
      VpcID:
        Description: VPC id
        Value: !Ref VPC
        Export:
          Name:
            Fn::Sub: "${AWS::StackName}-VpcID"
      SubnetA:
        Description: public subnet
        Value: !Ref SubnetA
        Export:
          Name:
            Fn::Sub: "${AWS::StackName}-SubnetA"
      SubnetB:
        Description: public subnet 2
        Value: !Ref SubnetB
        Export:
          Name:
            Fn::Sub: "${AWS::StackName}-SubnetB"
      SubnetC:
        Description: priavte subnet
        Value: !Ref SubnetC
        Export:
          Name:
            Fn::Sub: "${AWS::StackName}-SubnetC"
      SubnetD:
        Description: private subnet 2
        Value: !Ref SubnetD
        Export:
          Name:
            Fn::Sub: "${AWS::StackName}-SubnetD"