From 327bd4f9c05afa1634358b2348c3ef9d615629c2 Mon Sep 17 00:00:00 2001 From: Rob Zienert Date: Fri, 6 Nov 2015 15:27:47 -0600 Subject: [PATCH 1/2] Adding S3 support for Lambda provider --- .../aws/resource_aws_lambda_function.go | 64 ++++++++++++++----- .../aws/r/lambda_function.html.markdown | 5 +- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/builtin/providers/aws/resource_aws_lambda_function.go b/builtin/providers/aws/resource_aws_lambda_function.go index 4ce898174..324016455 100644 --- a/builtin/providers/aws/resource_aws_lambda_function.go +++ b/builtin/providers/aws/resource_aws_lambda_function.go @@ -13,6 +13,8 @@ import ( "github.com/aws/aws-sdk-go/service/lambda" "github.com/mitchellh/go-homedir" + "errors" + "github.com/hashicorp/terraform/helper/schema" ) @@ -25,13 +27,28 @@ func resourceAwsLambdaFunction() *schema.Resource { Schema: map[string]*schema.Schema{ "filename": &schema.Schema{ - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"s3_bucket", "s3_key", "s3_object_version"}, + }, + "s3_bucket": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"filename"}, + }, + "s3_key": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"filename"}, + }, + "s3_object_version": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"filename"}, }, "description": &schema.Schema{ Type: schema.TypeString, Optional: true, - ForceNew: true, // TODO make this editable }, "function_name": &schema.Schema{ Type: schema.TypeString, @@ -93,22 +110,36 @@ func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) e log.Printf("[DEBUG] Creating Lambda Function %s with role %s", functionName, iamRole) - filename, err := homedir.Expand(d.Get("filename").(string)) - if err != nil { - return err + var functionCode *lambda.FunctionCode + if v, ok := d.GetOk("filename"); ok { + filename, err := homedir.Expand(v.(string)) + if err != nil { + return err + } + zipfile, err := ioutil.ReadFile(filename) + if err != nil { + return err + } + d.Set("source_code_hash", sha256.Sum256(zipfile)) + functionCode = &lambda.FunctionCode{ + ZipFile: zipfile, + } + } else { + s3Bucket, bucketOk := d.GetOk("s3_bucket") + s3Key, keyOk := d.GetOk("s3_key") + s3ObjectVersion, versionOk := d.GetOk("s3_object_version") + if !bucketOk || !keyOk || !versionOk { + return errors.New("s3_bucket, s3_key and s3_object_version must all be set while using S3 code source") + } + functionCode = &lambda.FunctionCode{ + S3Bucket: aws.String(s3Bucket.(string)), + S3Key: aws.String(s3Key.(string)), + S3ObjectVersion: aws.String(s3ObjectVersion.(string)), + } } - zipfile, err := ioutil.ReadFile(filename) - if err != nil { - return err - } - d.Set("source_code_hash", sha256.Sum256(zipfile)) - - log.Printf("[DEBUG] ") params := &lambda.CreateFunctionInput{ - Code: &lambda.FunctionCode{ - ZipFile: zipfile, - }, + Code: functionCode, Description: aws.String(d.Get("description").(string)), FunctionName: aws.String(functionName), Handler: aws.String(d.Get("handler").(string)), @@ -118,6 +149,7 @@ func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) e Timeout: aws.Int64(int64(d.Get("timeout").(int))), } + var err error for i := 0; i < 5; i++ { _, err = conn.CreateFunction(params) if awsErr, ok := err.(awserr.Error); ok { diff --git a/website/source/docs/providers/aws/r/lambda_function.html.markdown b/website/source/docs/providers/aws/r/lambda_function.html.markdown index 4c931fbad..f9c1ea4a3 100644 --- a/website/source/docs/providers/aws/r/lambda_function.html.markdown +++ b/website/source/docs/providers/aws/r/lambda_function.html.markdown @@ -44,7 +44,10 @@ resource "aws_lambda_function" "test_lambda" { ## Argument Reference -* `filename` - (Required) A [zip file][2] containing your lambda function source code. +* `filename` - (Optional) A [zip file][2] containing your lambda function source code. If defined, The `s3_*` options cannot be used. +* `s3_bucket` - (Optional) The S3 bucket location containing your lambda function source code. Conflicts with `filename`. +* `s3_key` - (Optional) The S3 key containing your lambda function source code. Conflicts with `filename`. +* `s3_object_version` - (Optional) The object version of your lambda function source code. Conflicts with `filename`. * `function_name` - (Required) A unique name for your Lambda Function. * `handler` - (Required) The function [entrypoint][3] in your code. * `role` - (Required) IAM role attached to the Lambda Function. This governs both who / what can invoke your Lambda Function, as well as what resources our Lambda Function has access to. See [Lambda Permission Model][4] for more details. From 996f88acd8cab692cd26ea32c2c63dcb26dcb21a Mon Sep 17 00:00:00 2001 From: Clint Date: Fri, 6 Nov 2015 16:17:22 -0600 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5215c84e3..cdb5a393b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ IMPROVEMENTS: * provider/aws: Add notification topic ARN for ElastiCache clusters [GH-3674] * provider/aws: Add `kinesis_endpoint` for configuring Kinesis [GH-3255] * provider/aws: Add a computed ARN for S3 Buckets [GH-3685] + * provider/aws: Add S3 support for Lambda Function resource [GH-3794] * provider/aws: Add configuration to enable copying RDS tags to final snapshot [GH-3529] * provider/aws: RDS Cluster additions (`backup_retention_period`, `preferred_backup_window`, `preferred_maintenance_window`) [GH-3757] * provider/openstack: Use IPv4 as the defeault IP version for subnets [GH-3091]