Skip to content

Commit

Permalink
New Resource: aws_lambda_provisioned_concurrency_config (#11129)
Browse files Browse the repository at this point in the history
Output from acceptance testing:

```
--- PASS: TestAccAWSLambdaProvisionedConcurrencyConfig_disappears_LambdaProvisionedConcurrencyConfig (240.38s)
--- PASS: TestAccAWSLambdaProvisionedConcurrencyConfig_Qualifier_AliasName (246.42s)
--- PASS: TestAccAWSLambdaProvisionedConcurrencyConfig_basic (253.46s)
--- PASS: TestAccAWSLambdaProvisionedConcurrencyConfig_disappears_LambdaFunction (259.60s)
--- PASS: TestAccAWSLambdaProvisionedConcurrencyConfig_ProvisionedConcurrentExecutions (380.90s)
```
  • Loading branch information
bflad authored Dec 4, 2019
1 parent ee4aec8 commit c5efdda
Show file tree
Hide file tree
Showing 6 changed files with 645 additions and 0 deletions.
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ func Provider() terraform.ResourceProvider {
"aws_lambda_event_source_mapping": resourceAwsLambdaEventSourceMapping(),
"aws_lambda_alias": resourceAwsLambdaAlias(),
"aws_lambda_permission": resourceAwsLambdaPermission(),
"aws_lambda_provisioned_concurrency_config": resourceAwsLambdaProvisionedConcurrencyConfig(),
"aws_lambda_layer_version": resourceAwsLambdaLayerVersion(),
"aws_launch_configuration": resourceAwsLaunchConfiguration(),
"aws_launch_template": resourceAwsLaunchTemplate(),
Expand Down
37 changes: 37 additions & 0 deletions aws/resource_aws_lambda_function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,29 @@ func TestAccAWSLambdaFunction_basic(t *testing.T) {
})
}

func TestAccAWSLambdaFunction_disappears(t *testing.T) {
var function lambda.GetFunctionOutput

rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_lambda_function.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckLambdaFunctionDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSLambdaConfigBasic(rName, rName, rName, rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsLambdaFunctionExists(resourceName, rName, &function),
testAccCheckAwsLambdaFunctionDisappears(&function),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func TestAccAWSLambdaFunction_concurrency(t *testing.T) {
var conf lambda.GetFunctionOutput

Expand Down Expand Up @@ -1681,6 +1704,20 @@ func testAccCheckLambdaFunctionDestroy(s *terraform.State) error {

}

func testAccCheckAwsLambdaFunctionDisappears(function *lambda.GetFunctionOutput) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).lambdaconn

input := &lambda.DeleteFunctionInput{
FunctionName: function.Configuration.FunctionName,
}

_, err := conn.DeleteFunction(input)

return err
}
}

func testAccCheckAwsLambdaFunctionExists(res, funcName string, function *lambda.GetFunctionOutput) resource.TestCheckFunc {
// Wait for IAM role
return func(s *terraform.State) error {
Expand Down
211 changes: 211 additions & 0 deletions aws/resource_aws_lambda_provisioned_concurrency_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
package aws

import (
"fmt"
"log"
"strings"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/lambda"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)

func resourceAwsLambdaProvisionedConcurrencyConfig() *schema.Resource {
return &schema.Resource{
Create: resourceAwsLambdaProvisionedConcurrencyConfigCreate,
Read: resourceAwsLambdaProvisionedConcurrencyConfigRead,
Update: resourceAwsLambdaProvisionedConcurrencyConfigUpdate,
Delete: resourceAwsLambdaProvisionedConcurrencyConfigDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(15 * time.Minute),
Update: schema.DefaultTimeout(15 * time.Minute),
},

Schema: map[string]*schema.Schema{
"function_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.NoZeroValues,
},
"provisioned_concurrent_executions": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntAtLeast(1),
},
"qualifier": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.NoZeroValues,
},
},
}
}

func resourceAwsLambdaProvisionedConcurrencyConfigCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).lambdaconn
functionName := d.Get("function_name").(string)
qualifier := d.Get("qualifier").(string)

input := &lambda.PutProvisionedConcurrencyConfigInput{
FunctionName: aws.String(functionName),
ProvisionedConcurrentExecutions: aws.Int64(int64(d.Get("provisioned_concurrent_executions").(int))),
Qualifier: aws.String(qualifier),
}

_, err := conn.PutProvisionedConcurrencyConfig(input)

if err != nil {
return fmt.Errorf("error putting Lambda Provisioned Concurrency Config (%s:%s): %s", functionName, qualifier, err)
}

d.SetId(fmt.Sprintf("%s:%s", functionName, qualifier))

if err := waitForLambdaProvisionedConcurrencyConfigStatusReady(conn, functionName, qualifier, d.Timeout(schema.TimeoutCreate)); err != nil {
return fmt.Errorf("error waiting for Lambda Provisioned Concurrency Config (%s) to be ready: %s", d.Id(), err)
}

return resourceAwsLambdaProvisionedConcurrencyConfigRead(d, meta)
}

func resourceAwsLambdaProvisionedConcurrencyConfigRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).lambdaconn

functionName, qualifier, err := resourceAwsLambdaProvisionedConcurrencyConfigParseId(d.Id())

if err != nil {
return err
}

input := &lambda.GetProvisionedConcurrencyConfigInput{
FunctionName: aws.String(functionName),
Qualifier: aws.String(qualifier),
}

output, err := conn.GetProvisionedConcurrencyConfig(input)

if isAWSErr(err, lambda.ErrCodeProvisionedConcurrencyConfigNotFoundException, "") || isAWSErr(err, lambda.ErrCodeResourceNotFoundException, "") {
log.Printf("[WARN] Lambda Provisioned Concurrency Config (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return fmt.Errorf("error getting Lambda Provisioned Concurrency Config (%s): %s", d.Id(), err)
}

d.Set("function_name", functionName)
d.Set("provisioned_concurrent_executions", aws.Int64Value(output.AllocatedProvisionedConcurrentExecutions))
d.Set("qualifier", qualifier)

return nil
}

func resourceAwsLambdaProvisionedConcurrencyConfigUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).lambdaconn

functionName, qualifier, err := resourceAwsLambdaProvisionedConcurrencyConfigParseId(d.Id())

if err != nil {
return err
}

input := &lambda.PutProvisionedConcurrencyConfigInput{
FunctionName: aws.String(functionName),
ProvisionedConcurrentExecutions: aws.Int64(int64(d.Get("provisioned_concurrent_executions").(int))),
Qualifier: aws.String(qualifier),
}

_, err = conn.PutProvisionedConcurrencyConfig(input)

if err != nil {
return fmt.Errorf("error putting Lambda Provisioned Concurrency Config (%s:%s): %s", functionName, qualifier, err)
}

if err := waitForLambdaProvisionedConcurrencyConfigStatusReady(conn, functionName, qualifier, d.Timeout(schema.TimeoutUpdate)); err != nil {
return fmt.Errorf("error waiting for Lambda Provisioned Concurrency Config (%s) to be ready: %s", d.Id(), err)
}

return resourceAwsLambdaProvisionedConcurrencyConfigRead(d, meta)
}

func resourceAwsLambdaProvisionedConcurrencyConfigDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).lambdaconn

functionName, qualifier, err := resourceAwsLambdaProvisionedConcurrencyConfigParseId(d.Id())

if err != nil {
return err
}

input := &lambda.DeleteProvisionedConcurrencyConfigInput{
FunctionName: aws.String(functionName),
Qualifier: aws.String(qualifier),
}

_, err = conn.DeleteProvisionedConcurrencyConfig(input)

if isAWSErr(err, lambda.ErrCodeProvisionedConcurrencyConfigNotFoundException, "") || isAWSErr(err, lambda.ErrCodeResourceNotFoundException, "") {
return nil
}

if err != nil {
return fmt.Errorf("error putting Lambda Provisioned Concurrency Config (%s:%s): %s", functionName, qualifier, err)
}

return nil
}

func resourceAwsLambdaProvisionedConcurrencyConfigParseId(id string) (string, string, error) {
parts := strings.SplitN(id, ":", 2)

if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
return "", "", fmt.Errorf("unexpected format of ID (%s), expected FUNCTION_NAME:QUALIFIER", id)
}

return parts[0], parts[1], nil
}

func refreshLambdaProvisionedConcurrencyConfigStatus(conn *lambda.Lambda, functionName, qualifier string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
input := &lambda.GetProvisionedConcurrencyConfigInput{
FunctionName: aws.String(functionName),
Qualifier: aws.String(qualifier),
}

output, err := conn.GetProvisionedConcurrencyConfig(input)

if err != nil {
return "", "", err
}

status := aws.StringValue(output.Status)

if status == lambda.ProvisionedConcurrencyStatusEnumFailed {
return output, status, fmt.Errorf("status reason: %s", aws.StringValue(output.StatusReason))
}

return output, status, nil
}
}

func waitForLambdaProvisionedConcurrencyConfigStatusReady(conn *lambda.Lambda, functionName, qualifier string, timeout time.Duration) error {
stateConf := &resource.StateChangeConf{
Pending: []string{lambda.ProvisionedConcurrencyStatusEnumInProgress},
Target: []string{lambda.ProvisionedConcurrencyStatusEnumReady},
Refresh: refreshLambdaProvisionedConcurrencyConfigStatus(conn, functionName, qualifier),
Timeout: timeout,
Delay: 5 * time.Second,
}

_, err := stateConf.WaitForState()

return err
}
Loading

0 comments on commit c5efdda

Please sign in to comment.