Search code examples
aws-lambdaserverlessserverless-framework

How to add unequal number of VPC settings to diff AWS systems?


We have a code deployed in two different environments in AWS: test system and prod system.

In the test system, we have three subnets and one security group which have to be attached to the lambda.

In the prod system, we have one subnet and two security groups that have to be attached to the lambda. (I know it is not a good practice to have just one subnet).

I would like to declare these in the serverless.yml file itself. I tried

provider:
  name: aws
  runtime: python3.6
  stage: ${opt:stage, 'test'}
  lambdaHashingVersion: 20201221
  region: ${env:AWS_DEFAULT_REGION}
  vpc:
    securityGroupIds:
      - ${self:custom.securityGroupIds.${self:provider.stage}1}
      - ${self:custom.securityGroupIds.${self:provider.stage}2}
    subnetIds:
      - ${self:custom.subnetIds.${self:provider.stage}1}
      - ${self:custom.subnetIds.${self:provider.stage}2}
      - ${self:custom.subnetIds.${self:provider.stage}3}

custom:
  securityGroupIds:
    test1: sg-xxxxxxxxxxx
    test2: ''
    prod: sg-yyyyyyyyyyy
  subnetIds:
    test1: subnet-xxxxxxxxxx
    test2: subnet-yyyyyyyyyy
    test3: subnet-zzzzzzzzzz
    prod1: subnet-aaaaaaaaaa
    prod2: ''
    prod3: ''
  pythonRequirements:
    dockerizePip: non-linux

functions:
  ec-frankfurt:
    handler: lambda_function.lambda_handler
    timeout: 60
    memorySize: 512

When the code is deployed via CI/CD, it throws an error.

Resource handler returned message: "1 validation error detected: Value '[sg-xxxxxxxxxxx, ]' at 'vpcConfig.securityGroupIds' failed to satisfy constraint: Member must satisfy constraint: [Member must have length less than or equal to 1024, Member must have length greater than or equal to 0, Member must satisfy regular expression pattern: ^sg-[0-9a-zA-Z]*$]

Is there a way I can declare the VPC settings for this case?


Solution

  • I believe such approach might be more effective in your case:

    service: dummy
    
    provider:
      name: aws
      region: ${env:AWS_DEFAULT_REGION}
      vpc: ${self:custom.vpcConfig.${sls:stage}}
    
    custom:
      vpcConfig:
        test:
          securityGroupIds:
            - sg-fortesting
            - sg-fortesting2
          subnetIds:
            - subnet-fortesting2
            - subnet-fortesting
        prod:
          securityGroupIds:
            - sg-forprod
            - sg-forprod2
          subnetIds:
            - subnet-forprod2
            - subnet-forprod
    

    It feels (at least in my opinion) a bit more cleaner to separate whole configurations of VPC and just resolve it based on stage.