Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add VPC support to lambda functions #837

Merged
merged 12 commits into from
May 17, 2018
27 changes: 25 additions & 2 deletions chalice/deploy/deployer.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
RequestsConnectionError
from botocore.session import Session # noqa
import jmespath
from typing import Optional, Dict, List, Any, Set, cast # noqa
from typing import Optional, Dict, List, Any, Set, Tuple, cast # noqa

from chalice import app
from chalice.config import Config # noqa
Expand Down Expand Up @@ -231,6 +231,10 @@ def _get_mb(self, value):
return '%.1f MB' % (float(value) / (1024 ** 2))


class ChaliceBuildError(Exception):
pass


def create_default_deployer(session, config, ui):
# type: (Session, Config, UI) -> Deployer
client = TypedAWSClient(session)
Expand Down Expand Up @@ -547,6 +551,24 @@ def _create_role_reference(self, config, stage_name, function_name):
policy=policy,
)

def _get_vpc_params(self, function_name, config):
# type: (str, Config) -> Tuple[List[str], List[str]]
security_group_ids = config.security_group_ids
subnet_ids = config.subnet_ids
if security_group_ids and subnet_ids:
return security_group_ids, subnet_ids
elif not security_group_ids and not subnet_ids:
return [], []
else:
raise ChaliceBuildError(
"Invalid VPC params for function '%s', in order to configure "
"VPC for a Lambda function, you must provide the subnet_ids "
"as well as the security_group_ids, got subnet_ids: %s, "
"security_group_ids: %s" % (function_name,
subnet_ids,
security_group_ids)
)

def _build_lambda_function(self,
config, # type: Config
name, # type: str
Expand All @@ -559,9 +581,10 @@ def _build_lambda_function(self,
config.app_name, config.chalice_stage, name)
security_group_ids = config.security_group_ids
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mentioned this before but I think we can remove lines 582-586 because they are handled in the _get_vpc_params() method.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fixed now.

subnet_ids = config.subnet_ids
if security_group_ids is None or subnet_ids is None:
if security_group_ids is None and subnet_ids is None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this if statement still needed? It looks like it gets handled in _get_vpc_params and is not necessarily needed.

security_group_ids = []
subnet_ids = []
security_group_ids, subnet_ids = self._get_vpc_params(name, config)
function = models.LambdaFunction(
resource_name=name,
function_name=function_name,
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/deploy/test_deployer.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
from chalice.deploy.models import RecordResourceVariable
from chalice.deploy.models import JPSearch, BuiltinFunction, Instruction
from chalice.constants import LAMBDA_TRUST_POLICY, VPC_ATTACH_POLICY
from chalice.deploy.deployer import ChaliceBuildError


_SESSION = None
Expand Down Expand Up @@ -466,6 +467,19 @@ def foo(event, context):
traits=set([models.RoleTraits.VPC_NEEDED]),
)

def test_exception_raised_when_missing_vpc_params(self, lambda_app):
@lambda_app.lambda_function()
def foo(event, context):
pass

builder = ApplicationGraphBuilder()
config = self.create_config(lambda_app,
iam_role_arn='role:arn',
security_group_ids=['sg1', 'sg2'],
subnet_ids=[])
with pytest.raises(ChaliceBuildError):
builder.build(config, stage_name='dev')

def test_multiple_lambda_functions_share_role_and_package(self,
lambda_app):
# We're going to add another lambda_function to our app.
Expand Down