Skip to content

Commit

Permalink
Merge pull request #11600 from marcjay/ses-configuration-set-delivery…
Browse files Browse the repository at this point in the history
…-options

resource/aws_ses_configuration_set: Add delivery options to allow a TlsPolicy of Require to be specified
  • Loading branch information
anGie44 authored Feb 11, 2021
2 parents 35a0d7f + d0a2791 commit 00b3db8
Show file tree
Hide file tree
Showing 4 changed files with 294 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .changelog/11600.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_ses_configuration_set: Add `delivery_options` argument
```
87 changes: 85 additions & 2 deletions aws/resource_aws_ses_configuration_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,35 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ses"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

func resourceAwsSesConfigurationSet() *schema.Resource {
return &schema.Resource{
Create: resourceAwsSesConfigurationSetCreate,
Read: resourceAwsSesConfigurationSetRead,
Update: resourceAwsSesConfigurationSetUpdate,
Delete: resourceAwsSesConfigurationSetDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"delivery_options": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"tls_policy": {
Type: schema.TypeString,
Optional: true,
Default: ses.TlsPolicyOptional,
ValidateFunc: validation.StringInSlice(ses.TlsPolicy_Values(), false),
},
},
},
},
"name": {
Type: schema.TypeString,
Required: true,
Expand All @@ -41,19 +58,32 @@ func resourceAwsSesConfigurationSetCreate(d *schema.ResourceData, meta interface

_, err := conn.CreateConfigurationSet(createOpts)
if err != nil {
return fmt.Errorf("Error creating SES configuration set: %s", err)
return fmt.Errorf("error creating SES configuration set (%s): %w", configurationSetName, err)
}

d.SetId(configurationSetName)

if v, ok := d.GetOk("delivery_options"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
input := &ses.PutConfigurationSetDeliveryOptionsInput{
ConfigurationSetName: aws.String(configurationSetName),
DeliveryOptions: expandSesConfigurationSetDeliveryOptions(v.([]interface{})),
}

_, err := conn.PutConfigurationSetDeliveryOptions(input)
if err != nil {
return fmt.Errorf("error adding SES configuration set (%s) delivery options: %w", configurationSetName, err)
}
}

return resourceAwsSesConfigurationSetRead(d, meta)
}

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

configSetInput := &ses.DescribeConfigurationSetInput{
ConfigurationSetName: aws.String(d.Id()),
ConfigurationSetName: aws.String(d.Id()),
ConfigurationSetAttributeNames: aws.StringSlice([]string{ses.ConfigurationSetAttributeDeliveryOptions}),
}

response, err := conn.DescribeConfigurationSet(configSetInput)
Expand All @@ -67,11 +97,33 @@ func resourceAwsSesConfigurationSetRead(d *schema.ResourceData, meta interface{}
return err
}

if err := d.Set("delivery_options", flattenSesConfigurationSetDeliveryOptions(response.DeliveryOptions)); err != nil {
return fmt.Errorf("error setting delivery_options: %w", err)
}

d.Set("name", aws.StringValue(response.ConfigurationSet.Name))

return nil
}

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

if d.HasChange("delivery_options") {
input := &ses.PutConfigurationSetDeliveryOptionsInput{
ConfigurationSetName: aws.String(d.Id()),
DeliveryOptions: expandSesConfigurationSetDeliveryOptions(d.Get("delivery_options").([]interface{})),
}

_, err := conn.PutConfigurationSetDeliveryOptions(input)
if err != nil {
return fmt.Errorf("error updating SES configuration set (%s) delivery options: %w", d.Id(), err)
}
}

return resourceAwsSesConfigurationSetRead(d, meta)
}

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

Expand All @@ -82,3 +134,34 @@ func resourceAwsSesConfigurationSetDelete(d *schema.ResourceData, meta interface

return err
}

func expandSesConfigurationSetDeliveryOptions(l []interface{}) *ses.DeliveryOptions {
if len(l) == 0 || l[0] == nil {
return nil
}

tfMap, ok := l[0].(map[string]interface{})
if !ok {
return nil
}

options := &ses.DeliveryOptions{}

if v, ok := tfMap["tls_policy"].(string); ok && v != "" {
options.TlsPolicy = aws.String(v)
}

return options
}

func flattenSesConfigurationSetDeliveryOptions(options *ses.DeliveryOptions) []interface{} {
if options == nil {
return nil
}

m := map[string]interface{}{
"tls_policy": aws.StringValue(options.TlsPolicy),
}

return []interface{}{m}
}
191 changes: 187 additions & 4 deletions aws/resource_aws_ses_configuration_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ func testSweepSesConfigurationSets(region string) error {

func TestAccAWSSESConfigurationSet_basic(t *testing.T) {
var escRandomInteger = acctest.RandInt()
resourceName := "aws_ses_configuration_set.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
Expand All @@ -79,13 +80,175 @@ func TestAccAWSSESConfigurationSet_basic(t *testing.T) {
CheckDestroy: testAccCheckSESConfigurationSetDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSSESConfigurationSetConfig(escRandomInteger),
Config: testAccAWSSESConfigurationSetBasicConfig(escRandomInteger),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsSESConfigurationSetExists("aws_ses_configuration_set.test"),
testAccCheckAwsSESConfigurationSetExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "delivery_options.#", "0"),
),
},
{
ResourceName: "aws_ses_configuration_set.test",
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAWSSESConfigurationSet_deliveryOptions(t *testing.T) {
var escRandomInteger = acctest.RandInt()
resourceName := "aws_ses_configuration_set.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccPreCheckAWSSES(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckSESConfigurationSetDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSSESConfigurationSetDeliveryOptionsConfig(escRandomInteger, ses.TlsPolicyRequire),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsSESConfigurationSetExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "delivery_options.#", "1"),
resource.TestCheckResourceAttr(resourceName, "delivery_options.0.tls_policy", ses.TlsPolicyRequire),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAWSSESConfigurationSet_update_deliveryOptions(t *testing.T) {
var escRandomInteger = acctest.RandInt()
resourceName := "aws_ses_configuration_set.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccPreCheckAWSSES(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckSESConfigurationSetDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSSESConfigurationSetBasicConfig(escRandomInteger),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsSESConfigurationSetExists(resourceName),
),
},
{
Config: testAccAWSSESConfigurationSetDeliveryOptionsConfig(escRandomInteger, ses.TlsPolicyRequire),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsSESConfigurationSetExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "delivery_options.#", "1"),
resource.TestCheckResourceAttr(resourceName, "delivery_options.0.tls_policy", ses.TlsPolicyRequire),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccAWSSESConfigurationSetDeliveryOptionsConfig(escRandomInteger, ses.TlsPolicyOptional),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsSESConfigurationSetExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "delivery_options.#", "1"),
resource.TestCheckResourceAttr(resourceName, "delivery_options.0.tls_policy", ses.TlsPolicyOptional),
),
},
{
Config: testAccAWSSESConfigurationSetBasicConfig(escRandomInteger),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsSESConfigurationSetExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "delivery_options.#", "0"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAWSSESConfigurationSet_emptyDeliveryOptions(t *testing.T) {
var escRandomInteger = acctest.RandInt()
resourceName := "aws_ses_configuration_set.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccPreCheckAWSSES(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckSESConfigurationSetDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSSESConfigurationSetEmptyDeliveryOptionsConfig(escRandomInteger),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsSESConfigurationSetExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "delivery_options.#", "1"),
resource.TestCheckResourceAttr(resourceName, "delivery_options.0.tls_policy", ses.TlsPolicyOptional),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAWSSESConfigurationSet_update_emptyDeliveryOptions(t *testing.T) {
var escRandomInteger = acctest.RandInt()
resourceName := "aws_ses_configuration_set.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccPreCheckAWSSES(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckSESConfigurationSetDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSSESConfigurationSetBasicConfig(escRandomInteger),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsSESConfigurationSetExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "delivery_options.#", "0"),
),
},
{
Config: testAccAWSSESConfigurationSetEmptyDeliveryOptionsConfig(escRandomInteger),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsSESConfigurationSetExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "delivery_options.#", "1"),
resource.TestCheckResourceAttr(resourceName, "delivery_options.0.tls_policy", ses.TlsPolicyOptional),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccAWSSESConfigurationSetBasicConfig(escRandomInteger),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsSESConfigurationSetExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "delivery_options.#", "0"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
Expand Down Expand Up @@ -144,10 +307,30 @@ func testAccCheckSESConfigurationSetDestroy(s *terraform.State) error {
return nil
}

func testAccAWSSESConfigurationSetConfig(escRandomInteger int) string {
func testAccAWSSESConfigurationSetBasicConfig(escRandomInteger int) string {
return fmt.Sprintf(`
resource "aws_ses_configuration_set" "test" {
name = "some-configuration-set-%d"
}
`, escRandomInteger)
}

func testAccAWSSESConfigurationSetDeliveryOptionsConfig(escRandomInteger int, tlsPolicy string) string {
return fmt.Sprintf(`
resource "aws_ses_configuration_set" "test" {
name = "some-configuration-set-%d"
delivery_options {
tls_policy = %q
}
}
`, escRandomInteger, tlsPolicy)
}

func testAccAWSSESConfigurationSetEmptyDeliveryOptionsConfig(escRandomInteger int) string {
return fmt.Sprintf(`
resource "aws_ses_configuration_set" "test" {
name = "some-configuration-set-%d"
delivery_options {}
}
`, escRandomInteger)
}
19 changes: 19 additions & 0 deletions website/docs/r/ses_configuration_set.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,31 @@ resource "aws_ses_configuration_set" "test" {
}
```

### Require TLS Connections

```hcl
resource "aws_ses_configuration_set" "test" {
name = "some-configuration-set-test"
delivery_options {
tls_policy = "Require"
}
}
```

## Argument Reference

The following arguments are supported:

* `delivery_options` - (Optional) A configuration block that specifies whether messages that use the configuration set are required to use Transport Layer Security (TLS). Detailed below.
* `name` - (Required) The name of the configuration set

### delivery_options Argument Reference

The `delivery_options` configuration block supports the following argument:

* `tls_policy` - (Optional) Specifies whether messages that use the configuration set are required to use Transport Layer Security (TLS). If the value is `Require`, messages are only delivered if a TLS connection can be established. If the value is `Optional`, messages can be delivered in plain text if a TLS connection can't be established. Valid values: `Require` or `Optional`. Defaults to `Optional`.

## Import

SES Configuration Sets can be imported using their `name`, e.g.
Expand Down

0 comments on commit 00b3db8

Please sign in to comment.