Ask HN: How do I find why my AWS VPC is costing $34?

  • I had a $5 a month VPS that cost $300 a month to run because it didn't have enough RAM and was swap-happy and running up incredible I/O costs against EBS. The $10 a month VPS was a lot cheaper.

    In your case a Lambda could be cheaper still.

  • Cost explorer will help you dig into the usage type and resources used.

  • $34 screams “NAT Gateway.” Are you SURE you don’t have one? I’d bet a beer on it.

  • I did cloudformation stack deployments in December to my account. I am pretty sure that it is the ipv6 egress , which is supposed to be serverless and hence cheaper that NAT, that is responsible.

    Here is my cloudformation template for VPC:

    Resources: # VPC with IPv4 CIDR block BatchVpc: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true InstanceTenancy: default Tags: - Key: Name Value: !Sub '${AWS::StackName}-BatchVpc' - Key: stack Value: !Sub '${AWS::StackName}'

      # IPv6 CIDR Block for the VPC
      BatchVpcIpv6CidrBlock:
        Type: AWS::EC2::VPCCidrBlock
        Properties:
          VpcId: !Ref BatchVpc
          AmazonProvidedIpv6CidrBlock: true
    
      # Egress Only Internet Gateway for IPv6 traffic
      BatchEgressIgw:
        Type: AWS::EC2::EgressOnlyInternetGateway
        Properties:
          VpcId: !Ref BatchVpc
    
      # Security Group for SQS access
      BatchSgSqs:
        Type: AWS::EC2::SecurityGroup
        Properties:
          GroupDescription: Security group for SQS access
          VpcId: !Ref BatchVpc
          SecurityGroupIngress:
            - IpProtocol: tcp
              FromPort: 443
              ToPort: 443
              CidrIp: 10.0.0.0/16
          Tags: # Added tags
            - Key: Name
              Value: !Sub '${AWS::StackName}-BatchSgSqs'
            - Key: stack
              Value: !Sub '${AWS::StackName}'
    
      # Subnet for Batch instances (public subnet with IPv6)
      BatchSubnetPublicA: 
        Type: AWS::EC2::Subnet
        Properties:
          VpcId: !Ref BatchVpc
          AvailabilityZone: !Select [ 0, !GetAZs ]
          CidrBlock: 10.0.1.0/24 
          Ipv6CidrBlock: !Select [ 0, !Cidr [ !Select [ 0, !GetAtt BatchVpc.Ipv6CidrBlocks ], 1, 64 ] ]
          AssignIpv6AddressOnCreation: true
          Tags:
            - Key: Name
              Value: !Sub '${AWS::StackName}-BatchSubnetPublicA'
            - Key: stack
              Value: !Sub '${AWS::StackName}'
              
      # Route table for the subnet
      BatchRtbPublicA:
        Type: AWS::EC2::RouteTable
        Properties:
          VpcId: !Ref BatchVpc
          Tags:
            - Key: Name
              Value: !Sub '${AWS::StackName}-BatchRtbPublicA'
            - Key: stack
              Value: !Sub '${AWS::StackName}'
    
      # Associate subnet with route table
      BatchSubnetRtbAssocA: 
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
          SubnetId: !Ref BatchSubnetPublicA
          RouteTableId: !Ref BatchRtbPublicA
    
      # Route for IPv6 internet traffic
      BatchRouteIpv6Internet:
        Type: AWS::EC2::Route
        Properties:
          RouteTableId: !Ref BatchRtbPublicA
          DestinationIpv6CidrBlock: ::/0
          EgressOnlyInternetGatewayId: !Ref BatchEgressIgw
    
    
      # VPC Endpoint for S3
      BatchEpS3:
        Type: AWS::EC2::VPCEndpoint
        Properties:
          VpcId: !Ref BatchVpc
          ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3'
          RouteTableIds:
            - !Ref BatchRtbPublicA
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Principal: '*'
                Action:
                  - 's3:*'
                Resource: '*'
    
      # VPC Endpoint for SQS
      BatchEpSqs:
        Type: AWS::EC2::VPCEndpoint
        Properties:
          VpcId: !Ref BatchVpc
          VpcEndpointType: Interface
          ServiceName: !Sub 'com.amazonaws.${AWS::Region}.sqs'
          SubnetIds: 
            - !Ref BatchSubnetPublicA
          SecurityGroupIds:
            - !Ref BatchSgSqs
          PrivateDnsEnabled: true
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Principal: '*'
                Action:
                  - 'sqs:*' 
                Resource: '*'
    
    # for ECS BatchEpEcs: Type: AWS::EC2::VPCEndpoint Properties: VpcId: !Ref BatchVpc VpcEndpointType: Interface ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ecs' SubnetIds: - !Ref BatchSubnetPublicA SecurityGroupIds: - !Ref BatchSgSqs PrivateDnsEnabled: true PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: '' Action: 'ecs:' Resource: ''

      BatchEpEcsAgent:
        Type: AWS::EC2::VPCEndpoint
        Properties:
          VpcId: !Ref BatchVpc
          VpcEndpointType: Interface
          ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ecs-agent'
          SubnetIds:
            - !Ref BatchSubnetPublicA
          SecurityGroupIds:
            - !Ref BatchSgSqs
          PrivateDnsEnabled: true
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Principal: '*'
                Action: 'ecs:*'
                Resource: '*'
    
      BatchEpEcrApi:
        Type: AWS::EC2::VPCEndpoint
        Properties:
          VpcId: !Ref BatchVpc
          VpcEndpointType: Interface
          ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ecr.api'
          SubnetIds:
            - !Ref BatchSubnetPublicA
          SecurityGroupIds:
            - !Ref BatchSgSqs
          PrivateDnsEnabled: true
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Principal: '*'
                Action:
                  - ecr:GetAuthorizationToken
                  - ecr:BatchCheckLayerAvailability
                  - ecr:GetDownloadUrlForLayer
                  - ecr:BatchGetImage
                Resource: '*'
    
      BatchEpEcrDkr:
        Type: AWS::EC2::VPCEndpoint
        Properties:
          VpcId: !Ref BatchVpc
          VpcEndpointType: Interface
          ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ecr.dkr'
          SubnetIds:
            - !Ref BatchSubnetPublicA
          SecurityGroupIds:
            - !Ref BatchSgSqs
          PrivateDnsEnabled: true
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Principal: '*'
                Action:
                  - ecr:GetAuthorizationToken
                  - ecr:BatchCheckLayerAvailability
                  - ecr:GetDownloadUrlForLayer
                  - ecr:BatchGetImage
                Resource: '*'
      # VPC Endpoint for CloudWatch Logs          
      BatchEpCloudWatchLogs:
        Type: AWS::EC2::VPCEndpoint
        Properties:
          VpcId: !Ref BatchVpc
          VpcEndpointType: Interface
          ServiceName: !Sub 'com.amazonaws.${AWS::Region}.logs'
          SubnetIds: 
            - !Ref BatchSubnetPublicA
          SecurityGroupIds:
            - !Ref BatchSgSqs
          PrivateDnsEnabled: true
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Principal: '*'
                Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                  - 'logs:DescribeLogGroups'
                  - 'logs:DescribeLogStreams'
                Resource: '*'
    
    
    Outputs: BatchVpcId: Value: !Ref BatchVpc Export: Name: sandbox-infra-lite-CustomJob-batch-network:VpcId

      BatchSubnetId:
        Value: !Ref BatchSubnetPublicA
        Export:
          Name: sandbox-infra-lite-CustomJob-batch-network:BatchSubnetId
    
      BatchSgId:
        Value: !Ref BatchSgSqs
        Export:
          Name: sandbox-infra-lite-CustomJob-batch-network:BatchSgId