From 7ebe3289de6241ba69edf0a46452897675c23250 Mon Sep 17 00:00:00 2001 From: Albert Silva Date: Mon, 3 Apr 2023 15:54:33 -0400 Subject: [PATCH 01/10] add 'duration' and 'schedule_expression' attributes to rotation' --- .../service/secretsmanager/secret_rotation.go | 57 ++++++++++++++++--- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/internal/service/secretsmanager/secret_rotation.go b/internal/service/secretsmanager/secret_rotation.go index 3099ee3f1c5..1396d5d462c 100644 --- a/internal/service/secretsmanager/secret_rotation.go +++ b/internal/service/secretsmanager/secret_rotation.go @@ -3,6 +3,7 @@ package secretsmanager import ( "context" "log" + "regexp" "time" "github.com/aws/aws-sdk-go/aws" @@ -11,6 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" @@ -48,8 +50,28 @@ func ResourceSecretRotation() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "automatically_after_days": { - Type: schema.TypeInt, - Required: true, + Type: schema.TypeInt, + Optional: true, + ConflictsWith: []string{"rotation_rules.0.schedule_expression"}, + ExactlyOneOf: []string{"rotation_rules.0.automatically_after_days", "rotation_rules.0.schedule_expression"}, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + _, exists := d.GetOk("rotation_rules.0.schedule_expression") + return exists + }, + DiffSuppressOnRefresh: true, + ValidateFunc: validation.IntBetween(1, 1000), + }, + "duration": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`[0-9h]+`), ""), + }, + "schedule_expression": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"rotation_rules.0.automatically_after_days"}, + ExactlyOneOf: []string{"rotation_rules.0.automatically_after_days", "rotation_rules.0.schedule_expression"}, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`[0-9A-Za-z\(\)#\?\*\-\/, ]+`), ""), }, }, }, @@ -231,11 +253,20 @@ func expandRotationRules(l []interface{}) *secretsmanager.RotationRulesType { if len(l) == 0 { return nil } + rules := &secretsmanager.RotationRulesType{} + + tfMap := l[0].(map[string]interface{}) + + if v, ok := tfMap["automatically_after_days"].(int); ok && v != 0 { + rules.AutomaticallyAfterDays = aws.Int64(int64(v)) + } - m := l[0].(map[string]interface{}) + if v, ok := tfMap["duration"].(string); ok && v != "" { + rules.Duration = aws.String(v) + } - rules := &secretsmanager.RotationRulesType{ - AutomaticallyAfterDays: aws.Int64(int64(m["automatically_after_days"].(int))), + if v, ok := tfMap["schedule_expression"].(string); ok && v != "" { + rules.ScheduleExpression = aws.String(v) } return rules @@ -243,11 +274,21 @@ func expandRotationRules(l []interface{}) *secretsmanager.RotationRulesType { func flattenRotationRules(rules *secretsmanager.RotationRulesType) []interface{} { if rules == nil { - return []interface{}{} + return nil + } + + m := map[string]interface{}{} + + if v := rules.AutomaticallyAfterDays; v != nil { + m["automatically_after_days"] = int(aws.Int64Value(v)) + } + + if v := rules.Duration; v != nil { + m["duration"] = aws.StringValue(v) } - m := map[string]interface{}{ - "automatically_after_days": int(aws.Int64Value(rules.AutomaticallyAfterDays)), + if v := rules.ScheduleExpression; v != nil { + m["schedule_expression"] = aws.StringValue(v) } return []interface{}{m} From 24481ed5d1d23992902121516bde283dabadea58 Mon Sep 17 00:00:00 2001 From: Albert Silva Date: Mon, 3 Apr 2023 15:55:04 -0400 Subject: [PATCH 02/10] update schema to match updated flex functions --- internal/service/secretsmanager/secret.go | 25 +++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/internal/service/secretsmanager/secret.go b/internal/service/secretsmanager/secret.go index 97bec36e817..86c68ab1ce6 100644 --- a/internal/service/secretsmanager/secret.go +++ b/internal/service/secretsmanager/secret.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "log" + "regexp" "time" "github.com/aws/aws-sdk-go/aws" @@ -143,8 +144,28 @@ func ResourceSecret() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "automatically_after_days": { - Type: schema.TypeInt, - Required: true, + Type: schema.TypeInt, + Optional: true, + ConflictsWith: []string{"rotation_rules.0.schedule_expression"}, + ExactlyOneOf: []string{"rotation_rules.0.automatically_after_days", "rotation_rules.0.schedule_expression"}, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + _, exists := d.GetOk("rotation_rules.0.schedule_expression") + return exists + }, + DiffSuppressOnRefresh: true, + ValidateFunc: validation.IntBetween(1, 1000), + }, + "duration": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`[0-9h]+`), ""), + }, + "schedule_expression": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"rotation_rules.0.automatically_after_days"}, + ExactlyOneOf: []string{"rotation_rules.0.automatically_after_days", "rotation_rules.0.schedule_expression"}, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`[0-9A-Za-z\(\)#\?\*\-\/, ]+`), ""), }, }, }, From 6c538836799512da5fc888aa0c1c93f851b23e80 Mon Sep 17 00:00:00 2001 From: Albert Silva Date: Mon, 3 Apr 2023 15:55:32 -0400 Subject: [PATCH 03/10] add tests for 'duration' and 'schedule_expression' rotation attributes --- .../secretsmanager/secret_rotation_test.go | 192 +++++++++++++++++- 1 file changed, 189 insertions(+), 3 deletions(-) diff --git a/internal/service/secretsmanager/secret_rotation_test.go b/internal/service/secretsmanager/secret_rotation_test.go index 7420743341c..bfe627b0b40 100644 --- a/internal/service/secretsmanager/secret_rotation_test.go +++ b/internal/service/secretsmanager/secret_rotation_test.go @@ -3,6 +3,7 @@ package secretsmanager_test import ( "context" "fmt" + "strconv" "testing" "github.com/aws/aws-sdk-go/aws" @@ -21,7 +22,7 @@ func TestAccSecretsManagerSecretRotation_basic(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_secretsmanager_secret_rotation.test" lambdaFunctionResourceName := "aws_lambda_function.test1" - + days01 := 7 resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) }, ErrorCheck: acctest.ErrorCheck(t, secretsmanager.EndpointsID), @@ -30,13 +31,13 @@ func TestAccSecretsManagerSecretRotation_basic(t *testing.T) { Steps: []resource.TestStep{ // Test creating secret rotation resource { - Config: testAccSecretRotationConfig_basic(rName, 7), + Config: testAccSecretRotationConfig_basic(rName, days01), Check: resource.ComposeTestCheckFunc( testAccCheckSecretRotationExists(ctx, resourceName, &secret), resource.TestCheckResourceAttr(resourceName, "rotation_enabled", "true"), resource.TestCheckResourceAttrPair(resourceName, "rotation_lambda_arn", lambdaFunctionResourceName, "arn"), resource.TestCheckResourceAttr(resourceName, "rotation_rules.#", "1"), - resource.TestCheckResourceAttr(resourceName, "rotation_rules.0.automatically_after_days", "7"), + resource.TestCheckResourceAttr(resourceName, "rotation_rules.0.automatically_after_days", strconv.Itoa(days01)), ), }, // Test updating rotation @@ -62,6 +63,88 @@ func TestAccSecretsManagerSecretRotation_basic(t *testing.T) { }) } +func TestAccSecretsManagerSecretRotation_scheduleExpression(t *testing.T) { + ctx := acctest.Context(t) + var secret secretsmanager.DescribeSecretOutput + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_secretsmanager_secret_rotation.test" + lambdaFunctionResourceName := "aws_lambda_function.test1" + scheduleExpression := "rate(10 days)" + scheduleExpression02 := "rate(10 days)" + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, secretsmanager.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckSecretRotationDestroy(ctx), + Steps: []resource.TestStep{ + // Test creating secret rotation resource + { + Config: testAccSecretRotationConfig_scheduleExpression(rName, scheduleExpression), + Check: resource.ComposeTestCheckFunc( + testAccCheckSecretRotationExists(ctx, resourceName, &secret), + resource.TestCheckResourceAttr(resourceName, "rotation_enabled", "true"), + resource.TestCheckResourceAttrPair(resourceName, "rotation_lambda_arn", lambdaFunctionResourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "rotation_rules.#", "1"), + resource.TestCheckResourceAttr(resourceName, "rotation_rules.0.schedule_expression", scheduleExpression), + ), + }, + { + Config: testAccSecretRotationConfig_scheduleExpression(rName, scheduleExpression02), + Check: resource.ComposeTestCheckFunc( + testAccCheckSecretRotationExists(ctx, resourceName, &secret), + resource.TestCheckResourceAttr(resourceName, "rotation_enabled", "true"), + resource.TestCheckResourceAttrPair(resourceName, "rotation_lambda_arn", lambdaFunctionResourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "rotation_rules.#", "1"), + resource.TestCheckResourceAttr(resourceName, "rotation_rules.0.schedule_expression", scheduleExpression02), + ), + }, + // Test importing secret rotation + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccSecretsManagerSecretRotation_duration(t *testing.T) { + ctx := acctest.Context(t) + var secret secretsmanager.DescribeSecretOutput + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_secretsmanager_secret_rotation.test" + lambdaFunctionResourceName := "aws_lambda_function.test1" + days01 := 7 + duration := "3h" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, secretsmanager.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckSecretRotationDestroy(ctx), + Steps: []resource.TestStep{ + // Test creating secret rotation resource + { + Config: testAccSecretRotationConfig_duration(rName, days01, duration), + Check: resource.ComposeTestCheckFunc( + testAccCheckSecretRotationExists(ctx, resourceName, &secret), + resource.TestCheckResourceAttr(resourceName, "rotation_enabled", "true"), + resource.TestCheckResourceAttrPair(resourceName, "rotation_lambda_arn", lambdaFunctionResourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "rotation_rules.#", "1"), + resource.TestCheckResourceAttr(resourceName, "rotation_rules.0.automatically_after_days", strconv.Itoa(days01)), + resource.TestCheckResourceAttr(resourceName, "rotation_rules.0.duration", duration), + ), + }, + // Test importing secret rotation + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckSecretRotationDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).SecretsManagerConn() @@ -175,3 +258,106 @@ resource "aws_secretsmanager_secret_rotation" "test" { } `, rName, automaticallyAfterDays) } + +func testAccSecretRotationConfig_scheduleExpression(rName string, scheduleExpression string) string { + return acctest.ConfigLambdaBase(rName, rName, rName) + fmt.Sprintf(` +# Not a real rotation function +resource "aws_lambda_function" "test1" { + filename = "test-fixtures/lambdatest.zip" + function_name = "%[1]s-1" + handler = "exports.example" + role = aws_iam_role.iam_for_lambda.arn + runtime = "nodejs16.x" +} + +resource "aws_lambda_permission" "test1" { + action = "lambda:InvokeFunction" + function_name = aws_lambda_function.test1.function_name + principal = "secretsmanager.amazonaws.com" + statement_id = "AllowExecutionFromSecretsManager1" +} + +# Not a real rotation function +resource "aws_lambda_function" "test2" { + filename = "test-fixtures/lambdatest.zip" + function_name = "%[1]s-2" + handler = "exports.example" + role = aws_iam_role.iam_for_lambda.arn + runtime = "nodejs16.x" +} + +resource "aws_lambda_permission" "test2" { + action = "lambda:InvokeFunction" + function_name = aws_lambda_function.test2.function_name + principal = "secretsmanager.amazonaws.com" + statement_id = "AllowExecutionFromSecretsManager2" +} + +resource "aws_secretsmanager_secret" "test" { + name = "%[1]s" +} + +resource "aws_secretsmanager_secret_rotation" "test" { + secret_id = aws_secretsmanager_secret.test.id + rotation_lambda_arn = aws_lambda_function.test1.arn + + rotation_rules { + schedule_expression = "%[2]s" + } + + depends_on = [aws_lambda_permission.test1] +} +`, rName, scheduleExpression) +} + +func testAccSecretRotationConfig_duration(rName string, automaticallyAfterDays int, duration string) string { + return acctest.ConfigLambdaBase(rName, rName, rName) + fmt.Sprintf(` +# Not a real rotation function +resource "aws_lambda_function" "test1" { + filename = "test-fixtures/lambdatest.zip" + function_name = "%[1]s-1" + handler = "exports.example" + role = aws_iam_role.iam_for_lambda.arn + runtime = "nodejs16.x" +} + +resource "aws_lambda_permission" "test1" { + action = "lambda:InvokeFunction" + function_name = aws_lambda_function.test1.function_name + principal = "secretsmanager.amazonaws.com" + statement_id = "AllowExecutionFromSecretsManager1" +} + +# Not a real rotation function +resource "aws_lambda_function" "test2" { + filename = "test-fixtures/lambdatest.zip" + function_name = "%[1]s-2" + handler = "exports.example" + role = aws_iam_role.iam_for_lambda.arn + runtime = "nodejs16.x" +} + +resource "aws_lambda_permission" "test2" { + action = "lambda:InvokeFunction" + function_name = aws_lambda_function.test2.function_name + principal = "secretsmanager.amazonaws.com" + statement_id = "AllowExecutionFromSecretsManager2" +} + +resource "aws_secretsmanager_secret" "test" { + name = "%[1]s" +} + +resource "aws_secretsmanager_secret_rotation" "test" { + secret_id = aws_secretsmanager_secret.test.id + rotation_lambda_arn = aws_lambda_function.test1.arn + + rotation_rules { + automatically_after_days = %[2]d + duration = "%[3]s" + } + + depends_on = [aws_lambda_permission.test1] +} +`, rName, automaticallyAfterDays, duration) +} From e65cc645628626e24a079fa64883e8bfb5d0ea5e Mon Sep 17 00:00:00 2001 From: Albert Silva Date: Mon, 3 Apr 2023 15:55:46 -0400 Subject: [PATCH 04/10] add 'duration' and 'schedule_expression' attributes to rotation' --- website/docs/r/secretsmanager_secret_rotation.html.markdown | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/docs/r/secretsmanager_secret_rotation.html.markdown b/website/docs/r/secretsmanager_secret_rotation.html.markdown index 70e28b5f1d0..4eed9b49753 100644 --- a/website/docs/r/secretsmanager_secret_rotation.html.markdown +++ b/website/docs/r/secretsmanager_secret_rotation.html.markdown @@ -43,7 +43,9 @@ The following arguments are supported: ### rotation_rules -* `automatically_after_days` - (Required) Specifies the number of days between automatic scheduled rotations of the secret. +* `automatically_after_days` - (Optional) Specifies the number of days between automatic scheduled rotations of the secret. Either `automatically_after_days` or `schedule_expression` must be specified. +* `duration` - (Optional) - The length of the rotation window in hours. For example, `3h` for a three hour window. +* `schedule_expression` - (Optional) A `cron()` or `rate()` expression that defines the schedule for rotating your secret. Either `automatically_after_days` or `schedule_expression` must be specified. ## Attributes Reference From 518a6362cd49a12812608b56d1afb1ff96a90fe1 Mon Sep 17 00:00:00 2001 From: Albert Silva Date: Mon, 3 Apr 2023 16:02:54 -0400 Subject: [PATCH 05/10] add changelog --- .changelog/30425.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/30425.txt diff --git a/.changelog/30425.txt b/.changelog/30425.txt new file mode 100644 index 00000000000..a73a86b26aa --- /dev/null +++ b/.changelog/30425.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/secret_rotation: Add 'duration' and 'schedule_expression' attributes to rotation_rules block +``` From 59a8bb3edef31cdb0206b835b584b685394938c9 Mon Sep 17 00:00:00 2001 From: Albert Silva Date: Mon, 3 Apr 2023 16:24:56 -0400 Subject: [PATCH 06/10] terrafmt --- internal/service/secretsmanager/secret_rotation_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/secretsmanager/secret_rotation_test.go b/internal/service/secretsmanager/secret_rotation_test.go index bfe627b0b40..9a1fe9666ac 100644 --- a/internal/service/secretsmanager/secret_rotation_test.go +++ b/internal/service/secretsmanager/secret_rotation_test.go @@ -354,7 +354,7 @@ resource "aws_secretsmanager_secret_rotation" "test" { rotation_rules { automatically_after_days = %[2]d - duration = "%[3]s" + duration = "%[3]s" } depends_on = [aws_lambda_permission.test1] From 2f8fc7825ca674db2136b19ecec59f131eef21b0 Mon Sep 17 00:00:00 2001 From: Albert Silva Date: Tue, 4 Apr 2023 06:57:27 -0400 Subject: [PATCH 07/10] re-run ci From c4101e4c0d8391e398684af04124476f4285d04e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 4 Apr 2023 08:28:57 -0400 Subject: [PATCH 08/10] Tweak CHANGELOG entries. --- .changelog/30425.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.changelog/30425.txt b/.changelog/30425.txt index a73a86b26aa..d7155dc1cd0 100644 --- a/.changelog/30425.txt +++ b/.changelog/30425.txt @@ -1,3 +1,7 @@ ```release-note:enhancement -resource/secret_rotation: Add 'duration' and 'schedule_expression' attributes to rotation_rules block +resource/aws_secretsmanager_secret: Add `duration` and `schedule_expression` attributes to `rotation_rules` configuration block ``` + +```release-note:enhancement +resource/aws_secretsmanager_secret_rotation: Add `duration` and `schedule_expression` attributes to `rotation_rules` configuration block +``` \ No newline at end of file From 00ce527d3ddebd0525b068e5f5f0bfe94d511d70 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 4 Apr 2023 08:31:17 -0400 Subject: [PATCH 09/10] d/aws_secretsmanager_secret: Add `rotation_rules.duration` and `rotation_rules.schedule_expression` attributes. --- .changelog/30425.txt | 8 ++++++-- internal/service/secretsmanager/secret_data_source.go | 8 ++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.changelog/30425.txt b/.changelog/30425.txt index d7155dc1cd0..90e9a1829c2 100644 --- a/.changelog/30425.txt +++ b/.changelog/30425.txt @@ -1,7 +1,11 @@ ```release-note:enhancement -resource/aws_secretsmanager_secret: Add `duration` and `schedule_expression` attributes to `rotation_rules` configuration block +resource/aws_secretsmanager_secret: Add `duration` and `schedule_expression` attributes to `rotation_rules` configuration block ``` ```release-note:enhancement -resource/aws_secretsmanager_secret_rotation: Add `duration` and `schedule_expression` attributes to `rotation_rules` configuration block +resource/aws_secretsmanager_secret_rotation: Add `duration` and `schedule_expression` attributes to `rotation_rules` configuration block +``` + +```release-note:enhancement +data-source/aws_secretsmanager_secret: Add `rotation_rules.duration` and `rotation_rules.schedule_expression` attributes ``` \ No newline at end of file diff --git a/internal/service/secretsmanager/secret_data_source.go b/internal/service/secretsmanager/secret_data_source.go index b56f52f7730..8045f0c3726 100644 --- a/internal/service/secretsmanager/secret_data_source.go +++ b/internal/service/secretsmanager/secret_data_source.go @@ -64,6 +64,14 @@ func DataSourceSecret() *schema.Resource { Type: schema.TypeInt, Computed: true, }, + "duration": { + Type: schema.TypeString, + Computed: true, + }, + "schedule_expression": { + Type: schema.TypeString, + Computed: true, + }, }, }, }, From a97d45162ac13be66582d33b8ad49a20c1d50a62 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 4 Apr 2023 08:34:49 -0400 Subject: [PATCH 10/10] d/aws_secretsmanager_secret_rotation: Add `rotation_rules.duration` and `rotation_rules.schedule_expression` attributes. --- .changelog/30425.txt | 4 ++++ .../service/secretsmanager/secret_rotation_data_source.go | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/.changelog/30425.txt b/.changelog/30425.txt index 90e9a1829c2..24e83ebabe4 100644 --- a/.changelog/30425.txt +++ b/.changelog/30425.txt @@ -8,4 +8,8 @@ resource/aws_secretsmanager_secret_rotation: Add `duration` and `schedule_expres ```release-note:enhancement data-source/aws_secretsmanager_secret: Add `rotation_rules.duration` and `rotation_rules.schedule_expression` attributes +``` + +```release-note:enhancement +data-source/aws_secretsmanager_secret_rotation: Add `rotation_rules.duration` and `rotation_rules.schedule_expression` attributes ``` \ No newline at end of file diff --git a/internal/service/secretsmanager/secret_rotation_data_source.go b/internal/service/secretsmanager/secret_rotation_data_source.go index 7db107ee330..2065157b45f 100644 --- a/internal/service/secretsmanager/secret_rotation_data_source.go +++ b/internal/service/secretsmanager/secret_rotation_data_source.go @@ -41,6 +41,14 @@ func DataSourceSecretRotation() *schema.Resource { Type: schema.TypeInt, Computed: true, }, + "duration": { + Type: schema.TypeString, + Computed: true, + }, + "schedule_expression": { + Type: schema.TypeString, + Computed: true, + }, }, }, },