Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changelog/23873.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/aws_lambda_function: Add `ephemeral_storage` argument
```

```release-note:enhancement
data-source/aws_lambda_function: Add `ephemeral_storage` attribute
```
55 changes: 53 additions & 2 deletions internal/service/lambda/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,22 @@ func ResourceFunction() *schema.Resource {
},
},
},
"ephemeral_storage": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"size": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ValidateFunc: validation.IntBetween(512, 10240),
},
},
},
},
"file_system_config": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -378,10 +394,12 @@ func hasConfigChanges(d verify.ResourceDiffer) bool {
d.HasChange("layers") ||
d.HasChange("dead_letter_config") ||
d.HasChange("tracing_config") ||
d.HasChange("ephemeral_storage") ||
d.HasChange("vpc_config.0.security_group_ids") ||
d.HasChange("vpc_config.0.subnet_ids") ||
d.HasChange("runtime") ||
d.HasChange("environment")
d.HasChange("environment") ||
d.HasChange("ephemeral_storage")
}

// resourceAwsLambdaFunction maps to:
Expand Down Expand Up @@ -481,6 +499,14 @@ func resourceFunctionCreate(d *schema.ResourceData, meta interface{}) error {
}
}

if v, ok := d.GetOk("ephemeral_storage"); ok && len(v.([]interface{})) > 0 {
ephemeralStorage := v.([]interface{})
configMap := ephemeralStorage[0].(map[string]interface{})
params.EphemeralStorage = &lambda.EphemeralStorage{
Size: aws.Int64(int64(configMap["size"].(int))),
}
}

if v, ok := d.GetOk("file_system_config"); ok && len(v.([]interface{})) > 0 {
params.FileSystemConfigs = expandFileSystemConfigs(v.([]interface{}))
}
Expand Down Expand Up @@ -792,6 +818,12 @@ func resourceFunctionRead(d *schema.ResourceData, meta interface{}) error {
log.Printf("[ERR] Error setting environment for Lambda Function (%s): %s", d.Id(), err)
}

ephemeralStorage := flattenEphemeralStorage(function.EphemeralStorage)
log.Printf("[INFO] Setting Lambda %s ephemeralStorage %#v from API", d.Id(), ephemeralStorage)
if err := d.Set("ephemeral_storage", ephemeralStorage); err != nil {
return fmt.Errorf("error setting ephemeral_storage for Lambda Function (%s): %w", d.Id(), err)
}

if function.DeadLetterConfig != nil && function.DeadLetterConfig.TargetArn != nil {
d.Set("dead_letter_config", []interface{}{
map[string]interface{}{
Expand Down Expand Up @@ -983,7 +1015,15 @@ func resourceFunctionUpdate(d *schema.ResourceData, meta interface{}) error {
if d.HasChange("description") {
configReq.Description = aws.String(d.Get("description").(string))
}

if d.HasChange("ephemeral_storage") {
ephemeralStorage := d.Get("ephemeral_storage").([]interface{})
if len(ephemeralStorage) == 1 {
configMap := ephemeralStorage[0].(map[string]interface{})
configReq.EphemeralStorage = &lambda.EphemeralStorage{
Size: aws.Int64(int64(configMap["size"].(int))),
}
}
}
if d.HasChange("handler") {
configReq.Handler = aws.String(d.Get("handler").(string))
}
Expand Down Expand Up @@ -1444,3 +1484,14 @@ func expandImageConfigs(imageConfigMaps []interface{}) *lambda.ImageConfig {
}
return imageConfig
}

func flattenEphemeralStorage(response *lambda.EphemeralStorage) []map[string]interface{} {
if response == nil {
return nil
}

m := make(map[string]interface{})
m["size"] = aws.Int64Value(response.Size)

return []map[string]interface{}{m}
}
16 changes: 16 additions & 0 deletions internal/service/lambda/function_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ func DataSourceFunction() *schema.Resource {
},
},
},
"ephemeral_storage": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"size": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"file_system_config": {
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -356,5 +368,9 @@ func dataSourceFunctionRead(d *schema.ResourceData, meta interface{}) error {
return fmt.Errorf("Error setting architectures for Lambda Function (%s): %w", d.Id(), err)
}

if err := d.Set("ephemeral_storage", flattenEphemeralStorage(function.EphemeralStorage)); err != nil {
return fmt.Errorf("error setting ephemeral_storage: (%s): %w", d.Id(), err)
}

return nil
}
41 changes: 41 additions & 0 deletions internal/service/lambda/function_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,28 @@ func TestAccLambdaFunctionDataSource_architectures(t *testing.T) {
})
}

func TestAccLambdaFunctionDataSource_ephemeralStorage(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
dataSourceName := "data.aws_lambda_function.test"
resourceName := "aws_lambda_function.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, lambda.EndpointsID),
Providers: acctest.Providers,
Steps: []resource.TestStep{
{
Config: testAccFunctionEphemeralStorageDataSourceConfig(rName),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "ephemeral_storage.#", resourceName, "ephemeral_storage.#"),
resource.TestCheckResourceAttrPair(dataSourceName, "ephemeral_storage.0.size", resourceName, "ephemeral_storage.0.size"),
),
},
},
})
}

func testAccFunctionBaseDataSourceConfig(rName string) string {
return fmt.Sprintf(`
resource "aws_iam_role" "lambda" {
Expand Down Expand Up @@ -605,3 +627,22 @@ func testAccImagePreCheck(t *testing.T) {
t.Skip("AWS_LAMBDA_IMAGE_LATEST_ID env var must be set for Lambda Function Data Source Image Support acceptance tests.")
}
}

func testAccFunctionEphemeralStorageDataSourceConfig(rName string) string {
return testAccFunctionBaseDataSourceConfig(rName) + fmt.Sprintf(`
resource "aws_lambda_function" "test" {
filename = "test-fixtures/lambdatest.zip"
function_name = %[1]q
handler = "exports.example"
role = aws_iam_role.lambda.arn
runtime = "nodejs12.x"
ephemeral_storage {
size = 1024
}
}

data "aws_lambda_function" "test" {
function_name = aws_lambda_function.test.function_name
}
`, rName)
}
90 changes: 85 additions & 5 deletions internal/service/lambda/function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,19 @@ func TestAccLambdaFunction_basic(t *testing.T) {
Steps: []resource.TestStep{
{
Config: testAccBasicConfig(funcName, policyName, roleName, sgName),
Check: resource.ComposeTestCheckFunc(
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckFunctionExists(resourceName, funcName, &conf),
testAccCheckFunctionInvokeARN(resourceName, &conf),
testAccCheckFunctionName(&conf, funcName),
resource.TestCheckResourceAttr(resourceName, "architectures.#", "1"),
resource.TestCheckResourceAttr(resourceName, "architectures.0", lambda.ArchitectureX8664),
acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "lambda", fmt.Sprintf("function:%s", funcName)),
testAccCheckFunctionInvokeARN(resourceName, &conf),
resource.TestCheckResourceAttr(resourceName, "reserved_concurrent_executions", "-1"),
resource.TestCheckResourceAttr(resourceName, "version", tflambda.FunctionVersionLatest),
resource.TestCheckResourceAttr(resourceName, "ephemeral_storage.#", "1"),
resource.TestCheckResourceAttr(resourceName, "ephemeral_storage.0.size", "512"),
resource.TestCheckResourceAttr(resourceName, "package_type", lambda.PackageTypeZip),
resource.TestCheckResourceAttr(resourceName, "architectures.0", lambda.ArchitectureX8664),
acctest.CheckResourceAttrRegionalARN(resourceName, "qualified_arn", "lambda", fmt.Sprintf("function:%s:%s", funcName, tflambda.FunctionVersionLatest)),
resource.TestCheckResourceAttr(resourceName, "reserved_concurrent_executions", "-1"),
resource.TestCheckResourceAttr(resourceName, "version", tflambda.FunctionVersionLatest),
),
},
{
Expand Down Expand Up @@ -1194,6 +1197,51 @@ func TestAccLambdaFunction_architecturesWithLayer(t *testing.T) {
})
}

func TestAccLambdaFunction_ephemeralStorage(t *testing.T) {
var conf lambda.GetFunctionOutput
rString := sdkacctest.RandString(8)
funcName := fmt.Sprintf("tf_acc_lambda_func_ephemeral_storage_%s", rString)
policyName := fmt.Sprintf("tf_acc_policy_lambda_func_ephemeral_storage_%s", rString)
roleName := fmt.Sprintf("tf_acc_role_lambda_func_ephemeral_storage_%s", rString)
sgName := fmt.Sprintf("tf_acc_sg_lambda_func_ephemeral_storage_%s", rString)
resourceName := "aws_lambda_function.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(t)
},
ErrorCheck: acctest.ErrorCheck(t, lambda.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckFunctionDestroy,

Steps: []resource.TestStep{
{
Config: testAccWithEphemeralStorage(funcName, policyName, roleName, sgName),
Check: resource.ComposeTestCheckFunc(
testAccCheckFunctionExists(resourceName, funcName, &conf),
resource.TestCheckResourceAttr(resourceName, "ephemeral_storage.#", "1"),
resource.TestCheckResourceAttr(resourceName, "ephemeral_storage.0.size", "1024"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"filename", "publish"},
},
{
Config: testAccWithUpdateEphemeralStorage(funcName, policyName, roleName, sgName),
Check: resource.ComposeTestCheckFunc(
testAccCheckFunctionExists(resourceName, funcName, &conf),
testAccCheckFunctionName(&conf, funcName),
acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "lambda", fmt.Sprintf("function:%s", funcName)),
resource.TestCheckResourceAttr(resourceName, "ephemeral_storage.0.size", "2048"),
),
},
},
})
}

func TestAccLambdaFunction_tracing(t *testing.T) {
if testing.Short() {
t.Skip("skipping long-running test in short mode")
Expand Down Expand Up @@ -3597,3 +3645,35 @@ func testAccPreCheckSignerSigningProfile(t *testing.T, platformID string) {
t.Skipf("skipping acceptance testing: Signing Platform (%s) not found", platformID)
}
}

func testAccWithEphemeralStorage(funcName, policyName, roleName, sgName string) string {
return fmt.Sprintf(acctest.ConfigLambdaBase(policyName, roleName, sgName)+`
resource "aws_lambda_function" "test" {
filename = "test-fixtures/lambdatest.zip"
function_name = "%s"
role = aws_iam_role.iam_for_lambda.arn
handler = "exports.example"
runtime = "nodejs12.x"

ephemeral_storage {
size = 1024
}
}
`, funcName)
}

func testAccWithUpdateEphemeralStorage(funcName, policyName, roleName, sgName string) string {
return fmt.Sprintf(acctest.ConfigLambdaBase(policyName, roleName, sgName)+`
resource "aws_lambda_function" "test" {
filename = "test-fixtures/lambdatest.zip"
function_name = "%s"
role = aws_iam_role.iam_for_lambda.arn
handler = "exports.example"
runtime = "nodejs12.x"

ephemeral_storage {
size = 2048
}
}
`, funcName)
}
1 change: 1 addition & 0 deletions website/docs/d/lambda_function.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ In addition to all arguments above, the following attributes are exported:
* `dead_letter_config` - Configure the function's *dead letter queue*.
* `description` - Description of what your Lambda Function does.
* `environment` - The Lambda environment's configuration settings.
* `ephemeral_storage` - The amount of Ephemeral storage(`/tmp`) allocated for the Lambda Function.
* `file_system_config` - The connection settings for an Amazon EFS file system.
* `handler` - The function entrypoint in your code.
* `image_uri` - The URI of the container image.
Expand Down
43 changes: 43 additions & 0 deletions website/docs/r/lambda_function.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,44 @@ resource "aws_lambda_function" "example" {
}
```

### Lambda Ephemeral Storage

Lambda Function Ephemeral Storage(`/tmp`) allows you to configure the storage upto `10` GB. The default value set to `512` MB.

```terraform
resource "aws_iam_role" "iam_for_lambda" {
name = "iam_for_lambda"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "aws_lambda_function" "test_lambda" {
filename = "lambda_function_payload.zip"
function_name = "lambda_function_name"
role = aws_iam_role.iam_for_lambda.arn
handler = "index.test"
runtime = "nodejs14.x"

ephemeral_storage {
size = 10240 # Min 512 MB and the Max 10240 MB
}
}
```

### Lambda File Systems

Lambda File Systems allow you to connect an Amazon Elastic File System (EFS) file system to a Lambda function to share data across function invocations, access existing data including large files, and save function state.
Expand Down Expand Up @@ -223,6 +261,7 @@ The following arguments are optional:
* `dead_letter_config` - (Optional) Configuration block. Detailed below.
* `description` - (Optional) Description of what your Lambda Function does.
* `environment` - (Optional) Configuration block. Detailed below.
* `ephemeral_storage` - (Optional) The amount of Ephemeral storage(`/tmp`) to allocate for the Lambda Function in MB. This parameter is used to expand the total amount of Ephemeral storage available, beyond the default amount of `512`MB. Detailed below.
* `file_system_config` - (Optional) Configuration block. Detailed below.
* `filename` - (Optional) Path to the function's deployment package within the local filesystem. Conflicts with `image_uri`, `s3_bucket`, `s3_key`, and `s3_object_version`.
* `handler` - (Optional) Function [entrypoint][3] in your code.
Expand Down Expand Up @@ -254,6 +293,10 @@ Dead letter queue configuration that specifies the queue or topic where Lambda s

* `variables` - (Optional) Map of environment variables that are accessible from the function code during execution.

### ephemeral_storage

* `size` - (Required) The size of the Lambda function Ephemeral storage(`/tmp`) represented in MB. The minimum supported `ephemeral_storage` value defaults to `512`MB and the maximum supported value is `10240`MB.

### file_system_config

Connection settings for an EFS file system. Before creating or updating Lambda functions with `file_system_config`, EFS mount targets must be in available lifecycle state. Use `depends_on` to explicitly declare this dependency. See [Using Amazon EFS with Lambda][12].
Expand Down