🛠️ Demo thực tế: Làm việc với EBS & Instance Store Trên EC2 (script đầy đủ đi làm & đi thi)¶
Lesson Commands
Commands User¶
Instance 1¶
lsblk sudo file -s /dev/xvdf sudo mkfs -t xfs /dev/xvdf sudo file -s /dev/xvdf sudo mkdir /ebstest sudo mount /dev/xvdf /ebstest cd /ebstest sudo nano amazingtestfile.txt add a message save and exit ls -la
Reboot Instance 1¶
sudo reboot
Instance 1 After Reboot¶
df -k sudo blkid sudo nano /etc/fstab ADD LINE UUID=YOURUUIDHEREREPLACEME /ebstest xfs defaults,nofail sudo mount -a cd /ebstest ls -la
Instance 2¶
lsblk sudo file -s /dev/xvdf sudo mkdir /ebstest sudo mount /dev/xvdf /ebstest cd /ebstest ls -la
Instance 3¶
lsblk sudo file -s /dev/xvdf sudo mkdir /ebstest sudo mount /dev/xvdf /ebstest cd /ebstest ls -la
InstanceStoreTest¶
lsblk sudo file -s /dev/nvme1n1 sudo mkfs -t xfs /dev/nvme1n1 sudo file -s /dev/nvme1n1 sudo mkdir /instancestore sudo mount /dev/nvme1n1 /instancestore cd /instancestore sudo touch instancestore.txt
InstancStoreTest - After Restart¶
df -k its not there but we can mount it sudo mount /dev/nvme1n1 /instancestore cd /instancestore ls -la
InstanceStoreTest - After Stop/Start¶
sudo file -s /dev/nvme1n1
1. Bối cảnh & lưu ý chi phí¶
- Phần 1: Demo EBS & snapshot (trong Free Tier)
- Phần 2: Demo Instance Store (có thể mất phí, ~0.13$/giờ cho instance lớn, không Free Tier)
2. Chuẩn bị môi trường¶
- Đăng nhập AWS management account, chọn region N. Virginia (us-east-1)
- Dùng CloudFormation template để tạo sẵn 3 EC2 instances (2 ở AZ A, 1 ở AZ B)
- Mở EC2 Console > Instances, kiểm tra có 3 instance: instance-1a, instance-2a, instance-1ab
3. Kiểm tra EBS volumes¶
- EC2 Console > Elastic Block Store > Volumes
- Có 3 volume 8 GiB, mỗi cái gắn với 1 instance làm boot volume
4. Tạo EBS volume mới¶
- Create Volume
- Volume type: gp3
- Size: 10 GiB
- AZ: us-east-1a
- Tag: key = Name, value =EBS test volume
- Bấm Create volume, chờ trạng thái “available”
5. Attach volume vào EC2¶
- Chọn volume vừa tạo > Actions > Attach volume
- Chọn instance instance-1a (chỉ thấy instance cùng AZ)
- Device: /dev/sdf(Linux có thể nhận là/dev/xvdf)
- Bấm Attach
6. SSH/Connect vào EC2 instance¶
- EC2 Console > Instances > Chọn instance-1a > Connect > EC2 Instance Connect
- User: ec2-user
7. Thao tác trên Linux (copy, paste từng dòng)¶
# Xem block devices
lsblk
# Kiểm tra file system (vd: trên xvdf)
sudo file -s /dev/xvdf
# Nếu trả về "data", chưa có file system
# Tạo file system (XFS)
sudo mkfs -t xfs /dev/xvdf
# Kiểm tra lại file system
sudo file -s /dev/xvdf
# Tạo mount point
sudo mkdir /EBS-test
# Mount volume vào thư mục
sudo mount /dev/xvdf /EBS-test
# Kiểm tra mount
df -h
# Chuyển vào thư mục mount
cd /EBS-test
# Tạo file test
sudo nano amazing-test-file.txt
# (Nhập nội dung, Ctrl+O để lưu, Ctrl+X để thoát)
# Hiển thị nội dung file
cat amazing-test-file.txt
# Liệt kê file
ls -l
# Reboot instance để test persistence
sudo reboot
# (Đợi vài phút, sau đó connect lại instance)
8. Kiểm tra lại sau reboot¶
- SSH lại instance, chạy:
- File vẫn còn, chứng minh EBS là persistent storage
9. Kiến thức bổ sung & mẹo đi thi¶
- Chỉ attach EBS volume vào instance cùng AZ
- EBS volume tách rời vòng đời EC2: Dừng/xóa instance, volume vẫn còn (trừ khi chọn delete on termination)
- EBS volume dùng được cho nhiều EC2 (sequential attach, không parallel)
- Instance Store: Chỉ add khi launch, mất data khi stop/start/terminate, chỉ dùng cho temp/cache
- Boot volume chỉ dùng EBS, không dùng instance store
- EBS volume có thể tạo từ snapshot, restore/migrate/clone sang AZ/region khác
10. Lệnh tham khảo khác¶
# Format ext4 thay cho xfs
sudo mkfs.ext4 /dev/xvdf
# Unmount volume
sudo umount /EBS-test
# Xóa volume khỏi EC2 (detach)
# AWS Console > Volumes > Actions > Detach
11. Lưu ý chi phí¶
- EBS gp3: ~$0.08/GB/tháng (10GB ~ $0.8/tháng)
- Instance store: Không tính riêng, đã include trong giá EC2
- Part 2 (instance store): Dùng instance lớn tốn ~0.13$/giờ
- Snapshot: ~$0.05/GB/tháng trên data thực dùng
Tóm tắt: - EBS: Persistent, attach/detach linh hoạt, backup được (snapshot), chỉ attach cùng AZ. - Instance store: Hiệu năng cao, ephemeral, chỉ add lúc launch, mất data khi stop/start, không backup. - Thực hành đủ quy trình: tạo, attach, mount, test persistence, reboot, detach, xóa...
stack cloudformation
Description: Animals4Life base VPC Template + 3 Public Instances
Parameters:
  LatestAmiId:
    Description: AMI for EC2 (default is latest AmaLinux2023)
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.16.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: a4l-vpc1
  IPv6CidrBlock:
    Type: AWS::EC2::VPCCidrBlock
    Properties:
      VpcId: !Ref VPC
      AmazonProvidedIpv6CidrBlock: true
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: A4L-vpc1-igw
  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway
  RouteTableWeb:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: A4L-vpc1-rt-web
  RouteTableWebDefaultIPv4:
    Type: AWS::EC2::Route
    DependsOn: InternetGatewayAttachment
    Properties:
      RouteTableId: !Ref RouteTableWeb
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  RouteTableWebDefaultIPv6:
    Type: AWS::EC2::Route
    DependsOn: InternetGatewayAttachment
    Properties:
      RouteTableId: !Ref RouteTableWeb
      DestinationIpv6CidrBlock: '::/0'
      GatewayId: !Ref InternetGateway
  RouteTableAssociationWebA:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref SubnetWEBA
      RouteTableId: !Ref RouteTableWeb
  RouteTableAssociationWebB:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref SubnetWEBB
      RouteTableId: !Ref RouteTableWeb
  RouteTableAssociationWebC:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref SubnetWEBC
      RouteTableId: !Ref RouteTableWeb
  SubnetReservedA:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select
        - 0
        - !GetAZs ''
      CidrBlock: 10.16.0.0/20
      AssignIpv6AddressOnCreation: true
      Ipv6CidrBlock: !Sub
        - ${VpcPart}${SubnetPart}
        - SubnetPart: 00::/64
          VpcPart: !Select
            - 0
            - !Split
              - 00::/56
              - !Select
                - 0
                - !GetAtt VPC.Ipv6CidrBlocks
      Tags:
        - Key: Name
          Value: sn-reserved-A
  SubnetReservedB:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select
        - 1
        - !GetAZs ''
      CidrBlock: 10.16.64.0/20
      AssignIpv6AddressOnCreation: true
      Ipv6CidrBlock: !Sub
        - ${VpcPart}${SubnetPart}
        - SubnetPart: 04::/64
          VpcPart: !Select
            - 0
            - !Split
              - 00::/56
              - !Select
                - 0
                - !GetAtt VPC.Ipv6CidrBlocks
      Tags:
        - Key: Name
          Value: sn-reserved-B
  SubnetReservedC:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select
        - 2
        - !GetAZs ''
      CidrBlock: 10.16.128.0/20
      AssignIpv6AddressOnCreation: true
      Ipv6CidrBlock: !Sub
        - ${VpcPart}${SubnetPart}
        - SubnetPart: 08::/64
          VpcPart: !Select
            - 0
            - !Split
              - 00::/56
              - !Select
                - 0
                - !GetAtt VPC.Ipv6CidrBlocks
      Tags:
        - Key: Name
          Value: sn-reserved-C
  SubnetDBA:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select
        - 0
        - !GetAZs ''
      CidrBlock: 10.16.16.0/20
      AssignIpv6AddressOnCreation: true
      Ipv6CidrBlock: !Sub
        - ${VpcPart}${SubnetPart}
        - SubnetPart: 01::/64
          VpcPart: !Select
            - 0
            - !Split
              - 00::/56
              - !Select
                - 0
                - !GetAtt VPC.Ipv6CidrBlocks
      Tags:
        - Key: Name
          Value: sn-db-A
  SubnetDBB:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select
        - 1
        - !GetAZs ''
      CidrBlock: 10.16.80.0/20
      AssignIpv6AddressOnCreation: true
      Ipv6CidrBlock: !Sub
        - ${VpcPart}${SubnetPart}
        - SubnetPart: 05::/64
          VpcPart: !Select
            - 0
            - !Split
              - 00::/56
              - !Select
                - 0
                - !GetAtt VPC.Ipv6CidrBlocks
      Tags:
        - Key: Name
          Value: sn-db-B
  SubnetDBC:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select
        - 2
        - !GetAZs ''
      CidrBlock: 10.16.144.0/20
      AssignIpv6AddressOnCreation: true
      Ipv6CidrBlock: !Sub
        - ${VpcPart}${SubnetPart}
        - SubnetPart: 09::/64
          VpcPart: !Select
            - 0
            - !Split
              - 00::/56
              - !Select
                - 0
                - !GetAtt VPC.Ipv6CidrBlocks
      Tags:
        - Key: Name
          Value: sn-db-C
  SubnetAPPA:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select
        - 0
        - !GetAZs ''
      CidrBlock: 10.16.32.0/20
      AssignIpv6AddressOnCreation: true
      Ipv6CidrBlock: !Sub
        - ${VpcPart}${SubnetPart}
        - SubnetPart: 02::/64
          VpcPart: !Select
            - 0
            - !Split
              - 00::/56
              - !Select
                - 0
                - !GetAtt VPC.Ipv6CidrBlocks
      Tags:
        - Key: Name
          Value: sn-app-A
  SubnetAPPB:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select
        - 1
        - !GetAZs ''
      CidrBlock: 10.16.96.0/20
      AssignIpv6AddressOnCreation: true
      Ipv6CidrBlock: !Sub
        - ${VpcPart}${SubnetPart}
        - SubnetPart: 06::/64
          VpcPart: !Select
            - 0
            - !Split
              - 00::/56
              - !Select
                - 0
                - !GetAtt VPC.Ipv6CidrBlocks
      Tags:
        - Key: Name
          Value: sn-app-B
  SubnetAPPC:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select
        - 2
        - !GetAZs ''
      CidrBlock: 10.16.160.0/20
      AssignIpv6AddressOnCreation: true
      Ipv6CidrBlock: !Sub
        - ${VpcPart}${SubnetPart}
        - SubnetPart: 0A::/64
          VpcPart: !Select
            - 0
            - !Split
              - 00::/56
              - !Select
                - 0
                - !GetAtt VPC.Ipv6CidrBlocks
      Tags:
        - Key: Name
          Value: sn-app-C
  SubnetWEBA:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select
        - 0
        - !GetAZs ''
      CidrBlock: 10.16.48.0/20
      MapPublicIpOnLaunch: true
      Ipv6CidrBlock: !Sub
        - ${VpcPart}${SubnetPart}
        - SubnetPart: 03::/64
          VpcPart: !Select
            - 0
            - !Split
              - 00::/56
              - !Select
                - 0
                - !GetAtt VPC.Ipv6CidrBlocks
      Tags:
        - Key: Name
          Value: sn-web-A
  SubnetWEBB:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select
        - 1
        - !GetAZs ''
      CidrBlock: 10.16.112.0/20
      MapPublicIpOnLaunch: true
      Ipv6CidrBlock: !Sub
        - ${VpcPart}${SubnetPart}
        - SubnetPart: 07::/64
          VpcPart: !Select
            - 0
            - !Split
              - 00::/56
              - !Select
                - 0
                - !GetAtt VPC.Ipv6CidrBlocks
      Tags:
        - Key: Name
          Value: sn-web-B
  SubnetWEBC:
    Type: AWS::EC2::Subnet
    DependsOn: IPv6CidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select
        - 2
        - !GetAZs ''
      CidrBlock: 10.16.176.0/20
      MapPublicIpOnLaunch: true
      Ipv6CidrBlock: !Sub
        - ${VpcPart}${SubnetPart}
        - SubnetPart: 0B::/64
          VpcPart: !Select
            - 0
            - !Split
              - 00::/56
              - !Select
                - 0
                - !GetAtt VPC.Ipv6CidrBlocks
      Tags:
        - Key: Name
          Value: sn-web-C
  IPv6WorkaroundSubnetWEBA:
    Type: Custom::SubnetModify
    Properties:
      ServiceToken: !GetAtt IPv6WorkaroundLambda.Arn
      SubnetId: !Ref SubnetWEBA
  IPv6WorkaroundSubnetWEBB:
    Type: Custom::SubnetModify
    Properties:
      ServiceToken: !GetAtt IPv6WorkaroundLambda.Arn
      SubnetId: !Ref SubnetWEBB
  IPv6WorkaroundSubnetWEBC:
    Type: Custom::SubnetModify
    Properties:
      ServiceToken: !GetAtt IPv6WorkaroundLambda.Arn
      SubnetId: !Ref SubnetWEBC
  IPv6WorkaroundRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: !Sub ipv6-fix-logs-${AWS::StackName}
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: arn:aws:logs:*:*:*
        - PolicyName: !Sub ipv6-fix-modify-${AWS::StackName}
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - ec2:ModifySubnetAttribute
                Resource: '*'
  IPv6WorkaroundLambda:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.lambda_handler
      Code:
        #import cfnresponse below required to send respose back to CFN
        ZipFile: !Sub |
          import cfnresponse
          import boto3
          def lambda_handler(event, context):
            if event['RequestType'] is 'Delete':
              cfnresponse.send(event, context, cfnresponse.SUCCESS)
              return
            responseValue = event['ResourceProperties']['SubnetId']
            ec2 = boto3.client('ec2', region_name='${AWS::Region}')
            ec2.modify_subnet_attribute(AssignIpv6AddressOnCreation={
                            'Value': True
                            },
                            SubnetId=responseValue)
            responseData = {}
            responseData['SubnetId'] = responseValue
            cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
      Runtime: python3.9
      Role: !GetAtt IPv6WorkaroundRole.Arn
      Timeout: 30
  Instance1:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t2.micro
      ImageId: !Ref LatestAmiId
      IamInstanceProfile: !Ref SessionManagerInstanceProfile
      SubnetId: !Ref SubnetWEBA
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup
      Tags:
        - Key: Name
          Value: A4L-EBS-INSTANCE1-AZA
  Instance2:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t2.micro
      ImageId: !Ref LatestAmiId
      IamInstanceProfile: !Ref SessionManagerInstanceProfile
      SubnetId: !Ref SubnetWEBA
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup
      Tags:
        - Key: Name
          Value: A4L-EBS-INSTANCE2-AZA
  Instance3:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t2.micro
      ImageId: !Ref LatestAmiId
      IamInstanceProfile: !Ref SessionManagerInstanceProfile
      SubnetId: !Ref SubnetWEBB
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup
      Tags:
        - Key: Name
          Value: A4L-EBS-INSTANCE1-AZB
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VPC
      GroupDescription: Enable SSH access via port 22 IPv4 & v6
      SecurityGroupIngress:
        - Description: Allow SSH IPv4 IN
          IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 0.0.0.0/0
        - Description: Allow HTTP IPv4 IN
          IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
        - Description: Allow SSH IPv6 IN
          IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIpv6: '::/0'
  SessionManagerRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: root
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - ssm:DescribeAssociation
                  - ssm:GetDeployablePatchSnapshotForInstance
                  - ssm:GetDocument
                  - ssm:DescribeDocument
                  - ssm:GetManifest
                  - ssm:GetParameter
                  - ssm:GetParameters
                  - ssm:ListAssociations
                  - ssm:ListInstanceAssociations
                  - ssm:PutInventory
                  - ssm:PutComplianceItems
                  - ssm:PutConfigurePackageResult
                  - ssm:UpdateAssociationStatus
                  - ssm:UpdateInstanceAssociationStatus
                  - ssm:UpdateInstanceInformation
                Resource: '*'
              - Effect: Allow
                Action:
                  - ssmmessages:CreateControlChannel
                  - ssmmessages:CreateDataChannel
                  - ssmmessages:OpenControlChannel
                  - ssmmessages:OpenDataChannel
                Resource: '*'
              - Effect: Allow
                Action:
                  - ec2messages:AcknowledgeMessage
                  - ec2messages:DeleteMessage
                  - ec2messages:FailMessage
                  - ec2messages:GetEndpoint
                  - ec2messages:GetMessages
                  - ec2messages:SendReply
                Resource: '*'
  SessionManagerInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref SessionManagerRole
Outputs:
  a4lvpc1:
    Description: Animals4Life VPC1_ID
    Value: !Ref VPC
    Export:
      Name: a4l-vpc1
  a4lvpc1subnetweba:
    Description: Animals4Life VPC1 SubnetWEBA
    Value: !Ref SubnetWEBA
    Export:
      Name: a4l-vpc1-subnet-weba
  a4lvpc1subnetwebb:
    Description: Animals4Life VPC1 SubnetWEBB
    Value: !Ref SubnetWEBB
    Export:
      Name: a4l-vpc1-subnet-webb
  a4lvpc1subnetwebc:
    Description: Animals4Life VPC1 SubnetWEBC
    Value: !Ref SubnetWEBC
    Export:
      Name: a4l-vpc1-subnet-webc
  a4lvpc1subnetappa:
    Description: Animals4Life VPC1 SubnetAPPA
    Value: !Ref SubnetAPPA
    Export:
      Name: a4l-vpc1-subnet-appa
  a4lvpc1subnetappb:
    Description: Animals4Life VPC1 SubnetAPPB
    Value: !Ref SubnetAPPB
    Export:
      Name: a4l-vpc1-subnet-appb
  a4lvpc1subnetappc:
    Description: Animals4Life VPC1 SubnetAPPC
    Value: !Ref SubnetAPPC
    Export:
      Name: a4l-vpc1-subnet-appc
  a4lvpc1subnetdba:
    Description: Animals4Life VPC1 SubnetDBA
    Value: !Ref SubnetDBA
    Export:
      Name: a4l-vpc1-subnet-dba
  a4lvpc1subnetdbb:
    Description: Animals4Life VPC1 SubnetDBB
    Value: !Ref SubnetDBB
    Export:
      Name: a4l-vpc1-subnet-dbb
  a4lvpc1subnetdbc:
    Description: Animals4Life VPC1 SubnetDBC
    Value: !Ref SubnetDBC
    Export:
      Name: a4l-vpc1-subnet-dbc
  a4lvpc1subnetreserveda:
    Description: Animals4Life VPC1 SubnetReservedA
    Value: !Ref SubnetReservedA
    Export:
      Name: a4l-vpc1-subnet-reserveda
  a4lvpc1subnetreservedb:
    Description: Animals4Life VPC1 SubnetReservedB
    Value: !Ref SubnetReservedB
    Export:
      Name: a4l-vpc1-subnet-reservedb
  a4lvpc1subnetreservedc:
    Description: Animals4Life VPC1 SubnetReservedC
    Value: !Ref SubnetReservedC
    Export:
      Name: a4l-vpc1-subnet-reservedc