Skip to content

Commit a933880

Browse files
committed
support on-call rotations for ssmcontacts
1 parent a17a256 commit a933880

File tree

6 files changed

+146
-5
lines changed

6 files changed

+146
-5
lines changed

internal/service/ssmcontacts/contact.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1616
"github.com/hashicorp/terraform-provider-aws/internal/conns"
1717
"github.com/hashicorp/terraform-provider-aws/internal/create"
18+
"github.com/hashicorp/terraform-provider-aws/internal/flex"
1819
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
1920
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
2021
"github.com/hashicorp/terraform-provider-aws/names"
@@ -49,6 +50,13 @@ func ResourceContact() *schema.Resource {
4950
Type: schema.TypeString,
5051
Optional: true,
5152
},
53+
"rotation_ids": {
54+
Type: schema.TypeList,
55+
Optional: true,
56+
Elem: &schema.Schema{
57+
Type: schema.TypeString,
58+
},
59+
},
5260
names.AttrType: {
5361
Type: schema.TypeString,
5462
Required: true,
@@ -68,12 +76,23 @@ func resourceContactCreate(ctx context.Context, d *schema.ResourceData, meta any
6876
var diags diag.Diagnostics
6977
client := meta.(*conns.AWSClient).SSMContactsClient(ctx)
7078

79+
contactType := types.ContactType(d.Get(names.AttrType).(string))
80+
7181
input := &ssmcontacts.CreateContactInput{
7282
Alias: aws.String(d.Get(names.AttrAlias).(string)),
7383
DisplayName: aws.String(d.Get(names.AttrDisplayName).(string)),
74-
Plan: &types.Plan{Stages: []types.Stage{}},
7584
Tags: getTagsIn(ctx),
76-
Type: types.ContactType(d.Get(names.AttrType).(string)),
85+
Type: contactType,
86+
}
87+
88+
if contactType == types.ContactTypeOncallSchedule {
89+
plan := &types.Plan{}
90+
if v, ok := d.GetOk("rotation_ids"); ok {
91+
plan.RotationIds = flex.ExpandStringValueList(v.([]any))
92+
}
93+
input.Plan = plan
94+
} else {
95+
input.Plan = &types.Plan{Stages: []types.Stage{}}
7796
}
7897

7998
output, err := client.CreateContact(ctx, input)

internal/service/ssmcontacts/contact_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,3 +383,82 @@ resource "aws_ssmcontacts_contact" "contact_one" {
383383
}
384384
`, alias, displayName))
385385
}
386+
387+
func testAccContact_oncallSchedule(t *testing.T) {
388+
if testing.Short() {
389+
t.Skip("skipping long-running test in short mode")
390+
}
391+
392+
ctx := acctest.Context(t)
393+
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
394+
resourceName := "aws_ssmcontacts_contact.test"
395+
396+
resource.Test(t, resource.TestCase{
397+
PreCheck: func() {
398+
acctest.PreCheck(ctx, t)
399+
testAccContactPreCheck(ctx, t)
400+
},
401+
ErrorCheck: acctest.ErrorCheck(t, names.SSMContactsServiceID),
402+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
403+
CheckDestroy: testAccCheckContactDestroy(ctx),
404+
Steps: []resource.TestStep{
405+
{
406+
Config: testAccContactConfig_oncallSchedule(rName),
407+
Check: resource.ComposeTestCheckFunc(
408+
testAccCheckContactExists(ctx, resourceName),
409+
resource.TestCheckResourceAttr(resourceName, names.AttrAlias, rName),
410+
resource.TestCheckResourceAttr(resourceName, names.AttrType, "ONCALL_SCHEDULE"),
411+
resource.TestCheckResourceAttr(resourceName, "rotation_ids.#", "1"),
412+
acctest.MatchResourceAttrRegionalARN(ctx, resourceName, names.AttrARN, "ssm-contacts", regexache.MustCompile(`contact/.+$`)),
413+
),
414+
},
415+
{
416+
ResourceName: resourceName,
417+
ImportState: true,
418+
ImportStateVerify: true,
419+
},
420+
{
421+
Config: testAccContactConfig_none(),
422+
Check: testAccCheckContactDestroy(ctx),
423+
},
424+
},
425+
})
426+
}
427+
428+
func testAccContactConfig_oncallSchedule(alias string) string {
429+
return acctest.ConfigCompose(
430+
testAccContactConfig_base(),
431+
fmt.Sprintf(`
432+
resource "aws_ssmcontacts_contact" "test_contact" {
433+
alias = "%[1]s-contact"
434+
type = "PERSONAL"
435+
436+
depends_on = [aws_ssmincidents_replication_set.test]
437+
}
438+
439+
resource "aws_ssmcontacts_rotation" "test" {
440+
contact_ids = [aws_ssmcontacts_contact.test_contact.arn]
441+
name = %[1]q
442+
recurrence {
443+
number_of_on_calls = 1
444+
recurrence_multiplier = 1
445+
daily_settings {
446+
hour_of_day = 9
447+
minute_of_hour = 0
448+
}
449+
}
450+
time_zone_id = "America/Los_Angeles"
451+
452+
depends_on = [aws_ssmincidents_replication_set.test]
453+
}
454+
455+
resource "aws_ssmcontacts_contact" "test" {
456+
alias = %[1]q
457+
display_name = %[1]q
458+
type = "ONCALL_SCHEDULE"
459+
rotation_ids = [aws_ssmcontacts_rotation.test.arn]
460+
461+
depends_on = [aws_ssmincidents_replication_set.test]
462+
}
463+
`, alias))
464+
}

internal/service/ssmcontacts/helper.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ func setContactResourceData(d *schema.ResourceData, getContactOutput *ssmcontact
1616
d.Set(names.AttrAlias, getContactOutput.Alias)
1717
d.Set(names.AttrType, getContactOutput.Type)
1818
d.Set(names.AttrDisplayName, getContactOutput.DisplayName)
19+
if getContactOutput.Plan != nil && len(getContactOutput.Plan.RotationIds) > 0 {
20+
d.Set("rotation_ids", getContactOutput.Plan.RotationIds)
21+
}
1922

2023
return nil
2124
}

internal/service/ssmcontacts/ssmcontacts_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ func TestAccSSMContacts_serial(t *testing.T) {
2222
"updateDisplayName": testAccContact_updateDisplayName,
2323
"tags": testAccSSMContactsContact_tagsSerial,
2424
"updateType": testAccContact_updateType,
25+
"oncallSchedule": testAccContact_oncallSchedule,
2526
},
2627
"ContactDataSource": {
2728
acctest.CtBasic: testAccContactDataSource_basic,

website/docs/d/ssmcontacts_contact.html.markdown

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ This data source supports the following arguments:
3232
This data source exports the following attributes in addition to the arguments above:
3333

3434
* `alias` - A unique and identifiable alias of the contact or escalation plan.
35-
* `type` - The type of contact engaged. A single contact is type `PERSONAL` and an escalation plan is type `ESCALATION`.
35+
* `type` - The type of contact engaged. A single contact is type `PERSONAL`, an escalation plan is type `ESCALATION`, and an on-call schedule is type `ONCALL_SCHEDULE`.
3636
* `display_name` - Full friendly name of the contact or escalation plan.
37+
* `rotation_ids` - List of rotation IDs associated with the contact.
3738
* `tags` - Map of tags to assign to the resource.

website/docs/r/ssmcontacts_contact.html.markdown

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,56 @@ resource "aws_ssmcontacts_contact" "example" {
4141
}
4242
```
4343

44+
### On-call Schedule Usage
45+
46+
```terraform
47+
resource "aws_ssmcontacts_contact" "oncall_contact" {
48+
alias = "oncall-contact"
49+
type = "PERSONAL"
50+
51+
depends_on = [aws_ssmincidents_replication_set.example]
52+
}
53+
54+
resource "aws_ssmcontacts_rotation" "example" {
55+
contact_ids = [aws_ssmcontacts_contact.oncall_contact.arn]
56+
name = "example-rotation"
57+
58+
recurrence {
59+
number_of_on_calls = 1
60+
recurrence_multiplier = 1
61+
daily_settings {
62+
hour_of_day = 9
63+
minute_of_hour = 0
64+
}
65+
}
66+
67+
time_zone_id = "America/Los_Angeles"
68+
69+
depends_on = [aws_ssmincidents_replication_set.example]
70+
}
71+
72+
resource "aws_ssmcontacts_contact" "example" {
73+
alias = "oncall-schedule"
74+
display_name = "Example On-call Schedule"
75+
type = "ONCALL_SCHEDULE"
76+
rotation_ids = [aws_ssmcontacts_rotation.example.arn]
77+
78+
depends_on = [aws_ssmincidents_replication_set.example]
79+
}
80+
```
81+
4482
## Argument Reference
4583

4684
The following arguments are required:
4785

4886
- `alias` - (Required) A unique and identifiable alias for the contact or escalation plan. Must be between 1 and 255 characters, and may contain alphanumerics, underscores (`_`), and hyphens (`-`).
49-
- `type` - (Required) The type of contact engaged. A single contact is type PERSONAL and an escalation
50-
plan is type ESCALATION.
87+
- `type` - (Required) The type of contact engaged. A single contact is type `PERSONAL`, an escalation plan is type `ESCALATION`, and an on-call schedule is type `ONCALL_SCHEDULE`.
5188

5289
The following arguments are optional:
5390

5491
- `region` - (Optional) Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the [provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#aws-configuration-reference).
5592
- `display_name` - (Optional) Full friendly name of the contact or escalation plan. If set, must be between 1 and 255 characters, and may contain alphanumerics, underscores (`_`), hyphens (`-`), periods (`.`), and spaces.
93+
- `rotation_ids` - (Optional) List of rotation IDs associated with the contact. Required when `type` is `ONCALL_SCHEDULE`.
5694
- `tags` - (Optional) Key-value tags for the monitor. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.
5795

5896
## Attribute Reference

0 commit comments

Comments
 (0)