Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
19 changes: 19 additions & 0 deletions .changelog/45170.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
```release-note:enhancement
resource/aws_lambda_function: Add `tenancy_config` argument
```

```release-note:enhancement
data-source/aws_lambda_function: Add `tenancy_config` attribute
```

```release-note:enhancement
resource/aws_lambda_invocation: Add `tenant_id` argument
```

```release-note:enhancement
data-source/aws_lambda_invocation: Add `tenant_id` argument
```

```release-note:enhancement
action/aws_lambda_invoke: Add `tenant_id` argument
```
30 changes: 30 additions & 0 deletions internal/service/lambda/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,21 @@ func resourceFunction() *schema.Resource {
},
names.AttrTags: tftags.TagsSchema(),
names.AttrTagsAll: tftags.TagsSchemaComputed(),
"tenancy_config": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"tenant_isolation_mode": {
Type: schema.TypeString,
Required: true,
ValidateDiagFunc: enum.Validate[awstypes.TenantIsolationMode](),
},
},
},
},
names.AttrTimeout: {
Type: schema.TypeInt,
Optional: true,
Expand Down Expand Up @@ -585,6 +600,12 @@ func resourceFunctionCreate(ctx context.Context, d *schema.ResourceData, meta an
input.Code.SourceKMSKeyArn = aws.String(v.(string))
}

if v, ok := d.GetOk("tenancy_config"); ok && len(v.([]any)) > 0 && v.([]any)[0] != nil {
input.TenancyConfig = &awstypes.TenancyConfig{
TenantIsolationMode: awstypes.TenantIsolationMode(v.([]any)[0].(map[string]any)["tenant_isolation_mode"].(string)),
}
}

if v, ok := d.GetOk("tracing_config"); ok && len(v.([]any)) > 0 && v.([]any)[0] != nil {
input.TracingConfig = &awstypes.TracingConfig{
Mode: awstypes.TracingMode(v.([]any)[0].(map[string]any)[names.AttrMode].(string)),
Expand Down Expand Up @@ -752,6 +773,15 @@ func resourceFunctionRead(ctx context.Context, d *schema.ResourceData, meta any)
}); err != nil {
return sdkdiag.AppendErrorf(diags, "setting tracing_config: %s", err)
}
if function.TenancyConfig != nil {
if err := d.Set("tenancy_config", []any{
map[string]any{
"tenant_isolation_mode": string(function.TenancyConfig.TenantIsolationMode),
},
}); err != nil {
return sdkdiag.AppendErrorf(diags, "setting tenancy_config: %s", err)
}
}
if err := d.Set(names.AttrVPCConfig, flattenVPCConfigResponse(function.VpcConfig)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting vpc_config: %s", err)
}
Expand Down
21 changes: 21 additions & 0 deletions internal/service/lambda/function_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,18 @@ func dataSourceFunction() *schema.Resource {
Type: schema.TypeInt,
Computed: true,
},
"tenancy_config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"tenant_isolation_mode": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"tracing_config": {
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -365,6 +377,15 @@ func dataSourceFunctionRead(ctx context.Context, d *schema.ResourceData, meta an
d.Set("source_code_size", function.CodeSize)
d.Set("source_kms_key_arn", functionCode.SourceKMSKeyArn)
d.Set(names.AttrTimeout, function.Timeout)
if function.TenancyConfig != nil {
if err := d.Set("tenancy_config", []any{
map[string]any{
"tenant_isolation_mode": string(function.TenancyConfig.TenantIsolationMode),
},
}); err != nil {
return sdkdiag.AppendErrorf(diags, "setting tenancy_config: %s", err)
}
}
tracingConfigMode := awstypes.TracingModePassThrough
if function.TracingConfig != nil {
tracingConfigMode = function.TracingConfig.Mode
Expand Down
43 changes: 43 additions & 0 deletions internal/service/lambda/function_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,29 @@ func TestAccLambdaFunctionDataSource_loggingConfig(t *testing.T) {
})
}

func TestAccLambdaFunctionDataSource_tenancyConfig(t *testing.T) {
ctx := acctest.Context(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(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.LambdaServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccFunctionDataSourceConfig_tenancyConfig(rName),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, names.AttrARN, resourceName, names.AttrARN),
resource.TestCheckResourceAttrPair(dataSourceName, "tenancy_config.#", resourceName, "tenancy_config.#"),
resource.TestCheckResourceAttrPair(dataSourceName, "tenancy_config.0.tenant_isolation_mode", resourceName, "tenancy_config.0.tenant_isolation_mode"),
),
},
},
})
}

func testAccImageLatestPreCheck(t *testing.T) {
if os.Getenv("AWS_LAMBDA_IMAGE_LATEST_ID") == "" {
t.Skip("AWS_LAMBDA_IMAGE_LATEST_ID env var must be set for Lambda Function Data Source Image Support acceptance tests.")
Expand Down Expand Up @@ -850,3 +873,23 @@ data "aws_lambda_function" "test" {
}
`, rName, rName+"_custom"))
}

func testAccFunctionDataSourceConfig_tenancyConfig(rName string) string {
return acctest.ConfigCompose(testAccFunctionDataSourceConfig_base(rName), fmt.Sprintf(`
resource "aws_lambda_function" "test" {
filename = "test-fixtures/lambdatest.zip"
function_name = %[1]q
role = aws_iam_role.lambda.arn
handler = "exports.example"
runtime = "nodejs20.x"

tenancy_config {
tenant_isolation_mode = "PER_TENANT"
}
}

data "aws_lambda_function" "test" {
function_name = aws_lambda_function.test.function_name
}
`, rName))
}
84 changes: 84 additions & 0 deletions internal/service/lambda/function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2410,6 +2410,72 @@ func TestAccLambdaFunction_sourceKMSKeyARN(t *testing.T) {
})
}

func TestAccLambdaFunction_tenancyConfig(t *testing.T) {
ctx := acctest.Context(t)
var conf lambda.GetFunctionOutput
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_lambda_function.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.LambdaServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckFunctionDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccFunctionConfig_tenancyConfig(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckFunctionExists(ctx, resourceName, &conf),
resource.TestCheckResourceAttr(resourceName, "tenancy_config.#", "1"),
resource.TestCheckResourceAttr(resourceName, "tenancy_config.0.tenant_isolation_mode", "PER_TENANT"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"filename", "publish"},
},
},
})
}

func TestAccLambdaFunction_tenancyConfigForceNew(t *testing.T) {
ctx := acctest.Context(t)
var conf lambda.GetFunctionOutput
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_lambda_function.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.LambdaServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckFunctionDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccFunctionConfig_basic(rName, rName, rName, rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckFunctionExists(ctx, resourceName, &conf),
resource.TestCheckResourceAttr(resourceName, "tenancy_config.#", "0"),
),
},
{
Config: testAccFunctionConfig_tenancyConfig(rName),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionReplace),
},
},
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckFunctionExists(ctx, resourceName, &conf),
resource.TestCheckResourceAttr(resourceName, "tenancy_config.#", "1"),
resource.TestCheckResourceAttr(resourceName, "tenancy_config.0.tenant_isolation_mode", "PER_TENANT"),
),
},
},
})
}

func TestAccLambdaFunction_resetNonRefreshableAttributesAfterUpdateFailure(t *testing.T) {
ctx := acctest.Context(t)
var conf lambda.GetFunctionOutput
Expand Down Expand Up @@ -4364,6 +4430,24 @@ resource "aws_lambda_function" "test" {
`, rName, kmsIdentifier))
}

func testAccFunctionConfig_tenancyConfig(rName string) string {
return acctest.ConfigCompose(
acctest.ConfigLambdaBase(rName, rName, rName),
fmt.Sprintf(`
resource "aws_lambda_function" "test" {
filename = "test-fixtures/lambdatest.zip"
function_name = %[1]q
role = aws_iam_role.iam_for_lambda.arn
handler = "exports.example"
runtime = "nodejs20.x"

tenancy_config {
tenant_isolation_mode = "PER_TENANT"
}
}
`, rName))
}

func testAccFunctionConfig_skipDestroy(rName string) string {
return acctest.ConfigCompose(acctest.ConfigLambdaBase(rName, rName, rName), fmt.Sprintf(`
resource "aws_lambda_function" "test" {
Expand Down
7 changes: 7 additions & 0 deletions internal/service/lambda/invocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ func resourceInvocation() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"tenant_id": {
Type: schema.TypeString,
Optional: true,
},
"terraform_key": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -213,6 +217,9 @@ func invoke(ctx context.Context, conn *lambda.Client, d *schema.ResourceData, ac
Payload: payload,
Qualifier: aws.String(qualifier),
}
if v, ok := d.GetOk("tenant_id"); ok {
input.TenantId = aws.String(v.(string))
}

output, err := conn.Invoke(ctx, input)

Expand Down
8 changes: 8 additions & 0 deletions internal/service/lambda/invocation_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ func dataSourceInvocation() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"tenant_id": {
Type: schema.TypeString,
Optional: true,
},
},
}
}
Expand All @@ -61,6 +65,10 @@ func dataSourceInvocationRead(ctx context.Context, d *schema.ResourceData, meta
Qualifier: aws.String(qualifier),
}

if v, ok := d.GetOk("tenant_id"); ok {
input.TenantId = aws.String(v.(string))
}

output, err := conn.Invoke(ctx, input)

if err != nil {
Expand Down
54 changes: 54 additions & 0 deletions internal/service/lambda/invocation_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,26 @@ func TestAccLambdaInvocationDataSource_complex(t *testing.T) {
})
}

func TestAccLambdaInvocationDataSource_tenantId(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
testData := "value3"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.LambdaServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccInvocationDataSourceConfig_tenantId(rName, testData),
Check: resource.ComposeTestCheckFunc(
testAccCheckInvocationResult("data.aws_lambda_invocation.invocation_test", `{"key1":"value1","key2":"value2","key3":"`+testData+`"}`),
),
},
},
})
}

func testAccInvocationDataSource_base_config(roleName string) string {
return fmt.Sprintf(`
data "aws_iam_policy_document" "lambda_assume_role_policy" {
Expand Down Expand Up @@ -230,3 +250,37 @@ JSON
}
`, rName, testData)
}

func testAccInvocationDataSourceConfig_tenantId(rName, testData string) string {
return fmt.Sprintf(testAccInvocationDataSource_base_config(rName)+`
resource "aws_lambda_function" "lambda" {
depends_on = [aws_iam_role_policy_attachment.lambda_role_policy]

filename = "test-fixtures/lambda_invocation.zip"
function_name = "%s"
role = aws_iam_role.lambda_role.arn
handler = "lambda_invocation.handler"
runtime = "nodejs20.x"
tenancy_config {
tenant_isolation_mode = "PER_TENANT"
}

environment {
variables = {
TEST_DATA = "%s"
}
}
}

data "aws_lambda_invocation" "invocation_test" {
function_name = aws_lambda_function.lambda.function_name
tenant_id = "tenant-1"
input = <<JSON
{
"key1": "value1",
"key2": "value2"
}
JSON
}
`, rName, testData)
}
Loading
Loading