Skip to content

Commit

Permalink
r/aws_lambda_runtime_management_config: new resource
Browse files Browse the repository at this point in the history
This resource will allow practitioners to manage AWS Lambda runtime management configurations via Terraform.

```console
% make testacc PKG=lambda TESTS="TestAccLambdaRuntimeManagementConfig_"
==> Checking that code complies with gofmt requirements...
TF_ACC=1 go1.22.2 test ./internal/service/lambda/... -v -count 1 -parallel 20 -run='TestAccLambdaRuntimeManagementConfig_'  -timeout 360m

--- PASS: TestAccLambdaRuntimeManagementConfig_disappears_Function (37.05s)
--- PASS: TestAccLambdaRuntimeManagementConfig_basic (38.77s)
--- PASS: TestAccLambdaRuntimeManagementConfig_runtimeVersionARN (40.33s)
PASS
ok      github.com/hashicorp/terraform-provider-aws/internal/service/lambda     45.265s
```
  • Loading branch information
jar-b committed May 22, 2024
1 parent e788607 commit 69b4d62
Show file tree
Hide file tree
Showing 6 changed files with 573 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .changelog/37643.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_lambda_runtime_management_config
```
1 change: 1 addition & 0 deletions internal/service/lambda/exports_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var (
FindLayerVersionPolicyByTwoPartKey = findLayerVersionPolicyByTwoPartKey
FindPolicyStatementByTwoPartKey = findPolicyStatementByTwoPartKey
FindProvisionedConcurrencyConfigByTwoPartKey = findProvisionedConcurrencyConfigByTwoPartKey
FindRuntimeManagementConfigByTwoPartKey = findRuntimeManagementConfigByTwoPartKey
FunctionEventInvokeConfigParseResourceID = functionEventInvokeConfigParseResourceID
GetFunctionNameFromARN = getFunctionNameFromARN
GetQualifierFromAliasOrVersionARN = getQualifierFromAliasOrVersionARN
Expand Down
250 changes: 250 additions & 0 deletions internal/service/lambda/runtime_management_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package lambda

import (
"context"
"errors"
"fmt"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/lambda"
awstypes "github.com/aws/aws-sdk-go-v2/service/lambda/types"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-provider-aws/internal/create"
"github.com/hashicorp/terraform-provider-aws/internal/errs"
intflex "github.com/hashicorp/terraform-provider-aws/internal/flex"
"github.com/hashicorp/terraform-provider-aws/internal/framework"
"github.com/hashicorp/terraform-provider-aws/internal/framework/flex"
fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
"github.com/hashicorp/terraform-provider-aws/names"
)

// @FrameworkResource("aws_lambda_runtime_management_config", name="Runtime Management Config")
func newResourceRuntimeManagementConfig(_ context.Context) (resource.ResourceWithConfigure, error) {
return &resourceRuntimeManagementConfig{}, nil
}

const (
ResNameRuntimeManagementConfig = "Runtime Management Config"
runtimeManagementConfigIDParts = 2
)

type resourceRuntimeManagementConfig struct {
framework.ResourceWithConfigure
framework.WithNoOpDelete
}

func (r *resourceRuntimeManagementConfig) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = "aws_lambda_runtime_management_config"
}

func (r *resourceRuntimeManagementConfig) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
names.AttrFunctionARN: framework.ARNAttributeComputedOnly(),
"function_name": schema.StringAttribute{
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
"qualifier": schema.StringAttribute{
Optional: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
"runtime_version_arn": schema.StringAttribute{
CustomType: fwtypes.ARNType,
Optional: true,
},
"update_runtime_on": schema.StringAttribute{
CustomType: fwtypes.StringEnumType[awstypes.UpdateRuntimeOn](),
Optional: true,
},
},
}
}

func (r *resourceRuntimeManagementConfig) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
conn := r.Meta().LambdaClient(ctx)

var plan resourceRuntimeManagementConfigData
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
return
}

in := &lambda.PutRuntimeManagementConfigInput{}
resp.Diagnostics.Append(flex.Expand(ctx, plan, in)...)

out, err := conn.PutRuntimeManagementConfig(ctx, in)
if err != nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.Lambda, create.ErrActionCreating, ResNameRuntimeManagementConfig, plan.FunctionName.String(), err),
err.Error(),
)
return
}
if out == nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.Lambda, create.ErrActionCreating, ResNameRuntimeManagementConfig, plan.FunctionName.String(), nil),
errors.New("empty output").Error(),
)
return
}

resp.Diagnostics.Append(flex.Flatten(ctx, out, &plan)...)
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...)
}

func (r *resourceRuntimeManagementConfig) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
conn := r.Meta().LambdaClient(ctx)

var state resourceRuntimeManagementConfigData
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

out, err := findRuntimeManagementConfigByTwoPartKey(ctx, conn, state.FunctionName.ValueString(), state.Qualifier.ValueString())
if tfresource.NotFound(err) {
resp.State.RemoveResource(ctx)
return
}
if err != nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.Lambda, create.ErrActionSetting, ResNameRuntimeManagementConfig, state.FunctionName.String(), err),
err.Error(),
)
return
}

resp.Diagnostics.Append(flex.Flatten(ctx, out, &state)...)
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}

func (r *resourceRuntimeManagementConfig) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
conn := r.Meta().LambdaClient(ctx)

var plan, state resourceRuntimeManagementConfigData
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

if !plan.RuntimeVersionARN.Equal(state.RuntimeVersionARN) ||
!plan.UpdateRuntimeOn.Equal(state.UpdateRuntimeOn) {
in := &lambda.PutRuntimeManagementConfigInput{}
resp.Diagnostics.Append(flex.Expand(ctx, plan, in)...)

out, err := conn.PutRuntimeManagementConfig(ctx, in)
if err != nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.Lambda, create.ErrActionUpdating, ResNameRuntimeManagementConfig, plan.FunctionName.String(), err),
err.Error(),
)
return
}
if out == nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.Lambda, create.ErrActionUpdating, ResNameRuntimeManagementConfig, plan.FunctionName.String(), nil),
errors.New("empty output").Error(),
)
return
}

resp.Diagnostics.Append(flex.Flatten(ctx, out, &plan)...)
}

resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}

func (r *resourceRuntimeManagementConfig) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
conn := r.Meta().LambdaClient(ctx)

var state resourceRuntimeManagementConfigData
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

in := &lambda.PutRuntimeManagementConfigInput{
FunctionName: aws.String(state.FunctionName.ValueString()),
UpdateRuntimeOn: awstypes.UpdateRuntimeOnAuto,
}
if !state.Qualifier.IsNull() && state.Qualifier.ValueString() != "" {
in.Qualifier = aws.String(state.Qualifier.ValueString())
}

_, err := conn.PutRuntimeManagementConfig(ctx, in)
if err != nil {
if errs.IsA[*awstypes.ResourceNotFoundException](err) {
return
}
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.Lambda, create.ErrActionDeleting, ResNameRuntimeManagementConfig, state.FunctionName.String(), err),
err.Error(),
)
return
}
}

func (r *resourceRuntimeManagementConfig) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
parts, err := intflex.ExpandResourceId(req.ID, runtimeManagementConfigIDParts, true)
if err != nil {
resp.Diagnostics.AddError(
"Unexpected Import Identifier",
fmt.Sprintf("Expected import identifier with format: function_name,qualifier. Got: %q", req.ID),
)
return
}

resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("function_name"), parts[0])...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("qualifier"), parts[1])...)
}

func findRuntimeManagementConfigByTwoPartKey(ctx context.Context, conn *lambda.Client, functionName, qualifier string) (*lambda.GetRuntimeManagementConfigOutput, error) {
in := &lambda.GetRuntimeManagementConfigInput{
FunctionName: aws.String(functionName),
}
if qualifier != "" {
in.Qualifier = aws.String(qualifier)
}

out, err := conn.GetRuntimeManagementConfig(ctx, in)
if err != nil {
if errs.IsA[*awstypes.ResourceNotFoundException](err) {
return nil, &retry.NotFoundError{
LastError: err,
LastRequest: in,
}
}

return nil, err
}

if out == nil {
return nil, tfresource.NewEmptyResultError(in)
}

return out, nil
}

type resourceRuntimeManagementConfigData struct {
FunctionARN types.String `tfsdk:"function_arn"`
FunctionName types.String `tfsdk:"function_name"`
Qualifier types.String `tfsdk:"qualifier"`
RuntimeVersionARN fwtypes.ARN `tfsdk:"runtime_version_arn"`
UpdateRuntimeOn fwtypes.StringEnum[awstypes.UpdateRuntimeOn] `tfsdk:"update_runtime_on"`
}
Loading

0 comments on commit 69b4d62

Please sign in to comment.