Skip to content

Commit

Permalink
VPC config support in Lambda functions
Browse files Browse the repository at this point in the history
fixes #5105
  • Loading branch information
vincer committed Feb 16, 2016
1 parent 97af014 commit 3baabb0
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
51 changes: 51 additions & 0 deletions builtin/providers/aws/resource_aws_lambda_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,29 @@ func resourceAwsLambdaFunction() *schema.Resource {
Default: 3,
ForceNew: true, // TODO make this editable
},
"vpc_config": &schema.Schema{
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"subnet_ids": &schema.Schema{
Type: schema.TypeSet,
Required: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"security_group_ids": &schema.Schema{
Type: schema.TypeSet,
Required: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
},
},
},
"arn": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -149,6 +172,31 @@ func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) e
Timeout: aws.Int64(int64(d.Get("timeout").(int))),
}

if v, ok := d.GetOk("vpc_config"); ok {
configs := v.([]interface{})

if len(configs) > 1 {
return errors.New("Only a single vpc_config block is expected")
} else if len(configs) == 1 {
config := configs[0].(map[string]interface{})
var subnetIds []*string
for _, id := range config["subnet_ids"].(*schema.Set).List() {
subnetIds = append(subnetIds, aws.String(id.(string)))
}

var securityGroupIds []*string
for _, id := range config["security_group_ids"].(*schema.Set).List() {
securityGroupIds = append(securityGroupIds, aws.String(id.(string)))
}

var vpcConfig = &lambda.VpcConfig{
SubnetIds: subnetIds,
SecurityGroupIds: securityGroupIds,
}
params.VpcConfig = vpcConfig
}
}

// IAM profiles can take ~10 seconds to propagate in AWS:
// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#launch-instance-with-role-console
// Error creating Lambda function: InvalidParameterValueException: The role defined for the task cannot be assumed by Lambda.
Expand All @@ -157,10 +205,12 @@ func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) e
if err != nil {
if awserr, ok := err.(awserr.Error); ok {
if awserr.Code() == "InvalidParameterValueException" {
log.Printf("[DEBUG] InvalidParameterValueException creating Lambda Function: %s", awserr)
// Retryable
return awserr
}
}
log.Printf("[DEBUG] Error creating Lambda Function: %s", err)
// Not retryable
return resource.RetryError{Err: err}
}
Expand Down Expand Up @@ -207,6 +257,7 @@ func resourceAwsLambdaFunctionRead(d *schema.ResourceData, meta interface{}) err
d.Set("role", function.Role)
d.Set("runtime", function.Runtime)
d.Set("timeout", function.Timeout)
d.Set("vpc_config", flattenLambdaVpcConfigResponse(function.VpcConfig))

return nil
}
Expand Down
68 changes: 68 additions & 0 deletions builtin/providers/aws/resource_aws_lambda_function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,36 @@ func testAccCheckAWSLambdaAttributes(function *lambda.GetFunctionOutput) resourc
}

const testAccAWSLambdaConfig = `
resource "aws_iam_role_policy" "iam_policy_for_lambda" {
name = "iam_policy_for_lambda"
role = "${aws_iam_role.iam_for_lambda.id}"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterface"
],
"Resource": [
"*"
]
}
]
}
EOF
}
resource "aws_iam_role" "iam_for_lambda" {
name = "iam_for_lambda"
assume_role_policy = <<EOF
Expand All @@ -116,10 +146,48 @@ resource "aws_iam_role" "iam_for_lambda" {
EOF
}
resource "aws_vpc" "vpc_for_lambda" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "subnet_for_lambda" {
vpc_id = "${aws_vpc.vpc_for_lambda.id}"
cidr_block = "10.0.1.0/24"
tags {
Name = "lambda"
}
}
resource "aws_security_group" "sg_for_lambda" {
name = "sg_for_lambda"
description = "Allow all inbound traffic for lambda test"
vpc_id = "${aws_vpc.vpc_for_lambda.id}"
ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_lambda_function" "lambda_function_test" {
filename = "test-fixtures/lambdatest.zip"
function_name = "example_lambda_name"
role = "${aws_iam_role.iam_for_lambda.arn}"
handler = "exports.example"
vpc_config = {
subnet_ids = ["${aws_subnet.subnet_for_lambda.id}"]
security_group_ids = ["${aws_security_group.sg_for_lambda.id}"]
}
}
`
15 changes: 15 additions & 0 deletions builtin/providers/aws/structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/aws/aws-sdk-go/service/elasticache"
elasticsearch "github.com/aws/aws-sdk-go/service/elasticsearchservice"
"github.com/aws/aws-sdk-go/service/elb"
"github.com/aws/aws-sdk-go/service/lambda"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/aws/aws-sdk-go/service/redshift"
"github.com/aws/aws-sdk-go/service/route53"
Expand Down Expand Up @@ -680,6 +681,20 @@ func flattenDSVpcSettings(
return []map[string]interface{}{settings}
}

func flattenLambdaVpcConfigResponse(s *lambda.VpcConfigResponse) []map[string]interface{} {
settings := make(map[string]interface{}, 0)

if s == nil {
return nil
}

settings["subnet_ids"] = schema.NewSet(schema.HashString, flattenStringList(s.SubnetIds))
settings["security_group_ids"] = schema.NewSet(schema.HashString, flattenStringList(s.SecurityGroupIds))
settings["vpc_id"] = *s.VpcId

return []map[string]interface{}{settings}
}

func flattenDSConnectSettings(
customerDnsIps []*string,
s *directoryservice.DirectoryConnectSettingsDescription) []map[string]interface{} {
Expand Down

0 comments on commit 3baabb0

Please sign in to comment.