Skip to content

Commit c5efdda

Browse files
authored
New Resource: aws_lambda_provisioned_concurrency_config (#11129)
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) ```
1 parent ee4aec8 commit c5efdda

6 files changed

+645
-0
lines changed

aws/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,7 @@ func Provider() terraform.ResourceProvider {
598598
"aws_lambda_event_source_mapping": resourceAwsLambdaEventSourceMapping(),
599599
"aws_lambda_alias": resourceAwsLambdaAlias(),
600600
"aws_lambda_permission": resourceAwsLambdaPermission(),
601+
"aws_lambda_provisioned_concurrency_config": resourceAwsLambdaProvisionedConcurrencyConfig(),
601602
"aws_lambda_layer_version": resourceAwsLambdaLayerVersion(),
602603
"aws_launch_configuration": resourceAwsLaunchConfiguration(),
603604
"aws_launch_template": resourceAwsLaunchTemplate(),

aws/resource_aws_lambda_function_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,29 @@ func TestAccAWSLambdaFunction_basic(t *testing.T) {
9696
})
9797
}
9898

99+
func TestAccAWSLambdaFunction_disappears(t *testing.T) {
100+
var function lambda.GetFunctionOutput
101+
102+
rName := acctest.RandomWithPrefix("tf-acc-test")
103+
resourceName := "aws_lambda_function.test"
104+
105+
resource.ParallelTest(t, resource.TestCase{
106+
PreCheck: func() { testAccPreCheck(t) },
107+
Providers: testAccProviders,
108+
CheckDestroy: testAccCheckLambdaFunctionDestroy,
109+
Steps: []resource.TestStep{
110+
{
111+
Config: testAccAWSLambdaConfigBasic(rName, rName, rName, rName),
112+
Check: resource.ComposeTestCheckFunc(
113+
testAccCheckAwsLambdaFunctionExists(resourceName, rName, &function),
114+
testAccCheckAwsLambdaFunctionDisappears(&function),
115+
),
116+
ExpectNonEmptyPlan: true,
117+
},
118+
},
119+
})
120+
}
121+
99122
func TestAccAWSLambdaFunction_concurrency(t *testing.T) {
100123
var conf lambda.GetFunctionOutput
101124

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

16821705
}
16831706

1707+
func testAccCheckAwsLambdaFunctionDisappears(function *lambda.GetFunctionOutput) resource.TestCheckFunc {
1708+
return func(s *terraform.State) error {
1709+
conn := testAccProvider.Meta().(*AWSClient).lambdaconn
1710+
1711+
input := &lambda.DeleteFunctionInput{
1712+
FunctionName: function.Configuration.FunctionName,
1713+
}
1714+
1715+
_, err := conn.DeleteFunction(input)
1716+
1717+
return err
1718+
}
1719+
}
1720+
16841721
func testAccCheckAwsLambdaFunctionExists(res, funcName string, function *lambda.GetFunctionOutput) resource.TestCheckFunc {
16851722
// Wait for IAM role
16861723
return func(s *terraform.State) error {
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
package aws
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"strings"
7+
"time"
8+
9+
"github.com/aws/aws-sdk-go/aws"
10+
"github.com/aws/aws-sdk-go/service/lambda"
11+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
12+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
13+
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
14+
)
15+
16+
func resourceAwsLambdaProvisionedConcurrencyConfig() *schema.Resource {
17+
return &schema.Resource{
18+
Create: resourceAwsLambdaProvisionedConcurrencyConfigCreate,
19+
Read: resourceAwsLambdaProvisionedConcurrencyConfigRead,
20+
Update: resourceAwsLambdaProvisionedConcurrencyConfigUpdate,
21+
Delete: resourceAwsLambdaProvisionedConcurrencyConfigDelete,
22+
Importer: &schema.ResourceImporter{
23+
State: schema.ImportStatePassthrough,
24+
},
25+
Timeouts: &schema.ResourceTimeout{
26+
Create: schema.DefaultTimeout(15 * time.Minute),
27+
Update: schema.DefaultTimeout(15 * time.Minute),
28+
},
29+
30+
Schema: map[string]*schema.Schema{
31+
"function_name": {
32+
Type: schema.TypeString,
33+
Required: true,
34+
ForceNew: true,
35+
ValidateFunc: validation.NoZeroValues,
36+
},
37+
"provisioned_concurrent_executions": {
38+
Type: schema.TypeInt,
39+
Required: true,
40+
ValidateFunc: validation.IntAtLeast(1),
41+
},
42+
"qualifier": {
43+
Type: schema.TypeString,
44+
Required: true,
45+
ForceNew: true,
46+
ValidateFunc: validation.NoZeroValues,
47+
},
48+
},
49+
}
50+
}
51+
52+
func resourceAwsLambdaProvisionedConcurrencyConfigCreate(d *schema.ResourceData, meta interface{}) error {
53+
conn := meta.(*AWSClient).lambdaconn
54+
functionName := d.Get("function_name").(string)
55+
qualifier := d.Get("qualifier").(string)
56+
57+
input := &lambda.PutProvisionedConcurrencyConfigInput{
58+
FunctionName: aws.String(functionName),
59+
ProvisionedConcurrentExecutions: aws.Int64(int64(d.Get("provisioned_concurrent_executions").(int))),
60+
Qualifier: aws.String(qualifier),
61+
}
62+
63+
_, err := conn.PutProvisionedConcurrencyConfig(input)
64+
65+
if err != nil {
66+
return fmt.Errorf("error putting Lambda Provisioned Concurrency Config (%s:%s): %s", functionName, qualifier, err)
67+
}
68+
69+
d.SetId(fmt.Sprintf("%s:%s", functionName, qualifier))
70+
71+
if err := waitForLambdaProvisionedConcurrencyConfigStatusReady(conn, functionName, qualifier, d.Timeout(schema.TimeoutCreate)); err != nil {
72+
return fmt.Errorf("error waiting for Lambda Provisioned Concurrency Config (%s) to be ready: %s", d.Id(), err)
73+
}
74+
75+
return resourceAwsLambdaProvisionedConcurrencyConfigRead(d, meta)
76+
}
77+
78+
func resourceAwsLambdaProvisionedConcurrencyConfigRead(d *schema.ResourceData, meta interface{}) error {
79+
conn := meta.(*AWSClient).lambdaconn
80+
81+
functionName, qualifier, err := resourceAwsLambdaProvisionedConcurrencyConfigParseId(d.Id())
82+
83+
if err != nil {
84+
return err
85+
}
86+
87+
input := &lambda.GetProvisionedConcurrencyConfigInput{
88+
FunctionName: aws.String(functionName),
89+
Qualifier: aws.String(qualifier),
90+
}
91+
92+
output, err := conn.GetProvisionedConcurrencyConfig(input)
93+
94+
if isAWSErr(err, lambda.ErrCodeProvisionedConcurrencyConfigNotFoundException, "") || isAWSErr(err, lambda.ErrCodeResourceNotFoundException, "") {
95+
log.Printf("[WARN] Lambda Provisioned Concurrency Config (%s) not found, removing from state", d.Id())
96+
d.SetId("")
97+
return nil
98+
}
99+
100+
if err != nil {
101+
return fmt.Errorf("error getting Lambda Provisioned Concurrency Config (%s): %s", d.Id(), err)
102+
}
103+
104+
d.Set("function_name", functionName)
105+
d.Set("provisioned_concurrent_executions", aws.Int64Value(output.AllocatedProvisionedConcurrentExecutions))
106+
d.Set("qualifier", qualifier)
107+
108+
return nil
109+
}
110+
111+
func resourceAwsLambdaProvisionedConcurrencyConfigUpdate(d *schema.ResourceData, meta interface{}) error {
112+
conn := meta.(*AWSClient).lambdaconn
113+
114+
functionName, qualifier, err := resourceAwsLambdaProvisionedConcurrencyConfigParseId(d.Id())
115+
116+
if err != nil {
117+
return err
118+
}
119+
120+
input := &lambda.PutProvisionedConcurrencyConfigInput{
121+
FunctionName: aws.String(functionName),
122+
ProvisionedConcurrentExecutions: aws.Int64(int64(d.Get("provisioned_concurrent_executions").(int))),
123+
Qualifier: aws.String(qualifier),
124+
}
125+
126+
_, err = conn.PutProvisionedConcurrencyConfig(input)
127+
128+
if err != nil {
129+
return fmt.Errorf("error putting Lambda Provisioned Concurrency Config (%s:%s): %s", functionName, qualifier, err)
130+
}
131+
132+
if err := waitForLambdaProvisionedConcurrencyConfigStatusReady(conn, functionName, qualifier, d.Timeout(schema.TimeoutUpdate)); err != nil {
133+
return fmt.Errorf("error waiting for Lambda Provisioned Concurrency Config (%s) to be ready: %s", d.Id(), err)
134+
}
135+
136+
return resourceAwsLambdaProvisionedConcurrencyConfigRead(d, meta)
137+
}
138+
139+
func resourceAwsLambdaProvisionedConcurrencyConfigDelete(d *schema.ResourceData, meta interface{}) error {
140+
conn := meta.(*AWSClient).lambdaconn
141+
142+
functionName, qualifier, err := resourceAwsLambdaProvisionedConcurrencyConfigParseId(d.Id())
143+
144+
if err != nil {
145+
return err
146+
}
147+
148+
input := &lambda.DeleteProvisionedConcurrencyConfigInput{
149+
FunctionName: aws.String(functionName),
150+
Qualifier: aws.String(qualifier),
151+
}
152+
153+
_, err = conn.DeleteProvisionedConcurrencyConfig(input)
154+
155+
if isAWSErr(err, lambda.ErrCodeProvisionedConcurrencyConfigNotFoundException, "") || isAWSErr(err, lambda.ErrCodeResourceNotFoundException, "") {
156+
return nil
157+
}
158+
159+
if err != nil {
160+
return fmt.Errorf("error putting Lambda Provisioned Concurrency Config (%s:%s): %s", functionName, qualifier, err)
161+
}
162+
163+
return nil
164+
}
165+
166+
func resourceAwsLambdaProvisionedConcurrencyConfigParseId(id string) (string, string, error) {
167+
parts := strings.SplitN(id, ":", 2)
168+
169+
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
170+
return "", "", fmt.Errorf("unexpected format of ID (%s), expected FUNCTION_NAME:QUALIFIER", id)
171+
}
172+
173+
return parts[0], parts[1], nil
174+
}
175+
176+
func refreshLambdaProvisionedConcurrencyConfigStatus(conn *lambda.Lambda, functionName, qualifier string) resource.StateRefreshFunc {
177+
return func() (interface{}, string, error) {
178+
input := &lambda.GetProvisionedConcurrencyConfigInput{
179+
FunctionName: aws.String(functionName),
180+
Qualifier: aws.String(qualifier),
181+
}
182+
183+
output, err := conn.GetProvisionedConcurrencyConfig(input)
184+
185+
if err != nil {
186+
return "", "", err
187+
}
188+
189+
status := aws.StringValue(output.Status)
190+
191+
if status == lambda.ProvisionedConcurrencyStatusEnumFailed {
192+
return output, status, fmt.Errorf("status reason: %s", aws.StringValue(output.StatusReason))
193+
}
194+
195+
return output, status, nil
196+
}
197+
}
198+
199+
func waitForLambdaProvisionedConcurrencyConfigStatusReady(conn *lambda.Lambda, functionName, qualifier string, timeout time.Duration) error {
200+
stateConf := &resource.StateChangeConf{
201+
Pending: []string{lambda.ProvisionedConcurrencyStatusEnumInProgress},
202+
Target: []string{lambda.ProvisionedConcurrencyStatusEnumReady},
203+
Refresh: refreshLambdaProvisionedConcurrencyConfigStatus(conn, functionName, qualifier),
204+
Timeout: timeout,
205+
Delay: 5 * time.Second,
206+
}
207+
208+
_, err := stateConf.WaitForState()
209+
210+
return err
211+
}

0 commit comments

Comments
 (0)