-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Resource: aws_sns_sms_preferences #3858
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"strconv" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/sns" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceAwsSnsSmsPreferences() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsSnsSmsPreferencesSet, | ||
Read: resourceAwsSnsSmsPreferencesGet, | ||
Update: resourceAwsSnsSmsPreferencesSet, | ||
Delete: resourceAwsSnsSmsPreferencesDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"monthly_spend_limit": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"delivery_status_iam_role_arn": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"delivery_status_success_sampling_rate": { | ||
Type: schema.TypeString, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This probably should be a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above comment |
||
Optional: true, | ||
}, | ||
|
||
"default_sender_id": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"default_sms_type": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"usage_report_s3_bucket": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
const resourceId = "aws_sns_sms_id" | ||
|
||
var SMSAttributeMap = map[string]string{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need to export this I don't think? (same with the var below as well) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed, corrected |
||
"monthly_spend_limit": "MonthlySpendLimit", | ||
"delivery_status_iam_role_arn": "DeliveryStatusIAMRole", | ||
"delivery_status_success_sampling_rate": "DeliveryStatusSuccessSamplingRate", | ||
"default_sender_id": "DefaultSenderID", | ||
"default_sms_type": "DefaultSMSType", | ||
"usage_report_s3_bucket": "UsageReportS3Bucket", | ||
} | ||
|
||
var SMSAttributeDefaultValues = map[string]string{ | ||
"monthly_spend_limit": "", | ||
"delivery_status_iam_role_arn": "", | ||
"delivery_status_success_sampling_rate": "", | ||
"default_sender_id": "", | ||
"default_sms_type": "", | ||
"usage_report_s3_bucket": "", | ||
} | ||
|
||
func resourceAwsSnsSmsPreferencesSet(d *schema.ResourceData, meta interface{}) error { | ||
snsconn := meta.(*AWSClient).snsconn | ||
|
||
log.Printf("[DEBUG] SNS Set SMS preferences") | ||
|
||
monthlySpendLimit := d.Get("monthly_spend_limit").(string) | ||
monthlySpendLimitInt, _ := strconv.Atoi(monthlySpendLimit) | ||
deliveryStatusIamRoleArn := d.Get("delivery_status_iam_role_arn").(string) | ||
deliveryStatusSuccessSamplingRate := d.Get("delivery_status_success_sampling_rate").(string) | ||
deliveryStatusSuccessSamplingRateInt, _ := strconv.Atoi(deliveryStatusSuccessSamplingRate) | ||
defaultSenderId := d.Get("default_sender_id").(string) | ||
defaultSmsType := d.Get("default_sms_type").(string) | ||
usageReportS3Bucket := d.Get("usage_report_s3_bucket").(string) | ||
|
||
// Validation | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please move validation in to (for these other validations as well, more validations available in the |
||
if monthlySpendLimitInt < 0 { | ||
return fmt.Errorf("Error setting SMS preferences: monthly spend limit value [%d] must be >= 0!", monthlySpendLimitInt) | ||
} | ||
if deliveryStatusSuccessSamplingRateInt < 0 || deliveryStatusSuccessSamplingRateInt > 100 { | ||
return fmt.Errorf("Error setting SMS preferences: default percentage of success to sample value [%d] must be between 0 and 100!", deliveryStatusSuccessSamplingRateInt) | ||
} | ||
if defaultSmsType != "" && defaultSmsType != "Promotional" && defaultSmsType != "Transactional" { | ||
return fmt.Errorf("Error setting SMS preferences: default SMS type value [%s] is invalid!", defaultSmsType) | ||
} | ||
|
||
// Set preferences | ||
params := &sns.SetSMSAttributesInput{ | ||
Attributes: map[string]*string{ | ||
"MonthlySpendLimit": aws.String(monthlySpendLimit), | ||
"DeliveryStatusIAMRole": aws.String(deliveryStatusIamRoleArn), | ||
"DeliveryStatusSuccessSamplingRate": aws.String(deliveryStatusSuccessSamplingRate), | ||
"DefaultSenderID": aws.String(defaultSenderId), | ||
"DefaultSMSType": aws.String(defaultSmsType), | ||
"UsageReportS3Bucket": aws.String(usageReportS3Bucket), | ||
}, | ||
} | ||
|
||
if _, err := snsconn.SetSMSAttributes(params); err != nil { | ||
return fmt.Errorf("Error setting SMS preferences: %s", err) | ||
} | ||
|
||
d.SetId(resourceId) | ||
return nil | ||
} | ||
|
||
func resourceAwsSnsSmsPreferencesGet(d *schema.ResourceData, meta interface{}) error { | ||
snsconn := meta.(*AWSClient).snsconn | ||
|
||
// Fetch ALL attributes | ||
attrs, err := snsconn.GetSMSAttributes(&sns.GetSMSAttributesInput{}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Reset with default values first | ||
for tfAttrName, defValue := range SMSAttributeDefaultValues { | ||
d.Set(tfAttrName, defValue) | ||
} | ||
|
||
// Apply existing settings | ||
if attrs.Attributes != nil && len(attrs.Attributes) > 0 { | ||
attrmap := attrs.Attributes | ||
for tfAttrName, snsAttrName := range SMSAttributeMap { | ||
d.Set(tfAttrName, attrmap[snsAttrName]) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsSnsSmsPreferencesDelete(d *schema.ResourceData, meta interface{}) error { | ||
snsconn := meta.(*AWSClient).snsconn | ||
|
||
// Reset the attributes to their default value | ||
attrs := map[string]*string{} | ||
for tfAttrName, defValue := range SMSAttributeDefaultValues { | ||
attrs[SMSAttributeMap[tfAttrName]] = &defValue | ||
} | ||
|
||
params := &sns.SetSMSAttributesInput{Attributes: attrs} | ||
if _, err := snsconn.SetSMSAttributes(params); err != nil { | ||
return fmt.Errorf("Error resetting SMS preferences: %s", err) | ||
} | ||
|
||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestAccAWSSNSSMSPreferences_empty(t *testing.T) { | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckAWSSNSSMSPrefsDestroy, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testAccAWSSNSSMSPreferences_empty, | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckNoResourceAttr("aws_sns_sms_preferences.test_pref", "monthly_spend_limit"), | ||
resource.TestCheckNoResourceAttr("aws_sns_sms_preferences.test_pref", "delivery_status_iam_role_arn"), | ||
resource.TestCheckNoResourceAttr("aws_sns_sms_preferences.test_pref", "delivery_status_success_sampling_rate"), | ||
resource.TestCheckNoResourceAttr("aws_sns_sms_preferences.test_pref", "default_sender_id"), | ||
resource.TestCheckNoResourceAttr("aws_sns_sms_preferences.test_pref", "default_sms_type"), | ||
resource.TestCheckNoResourceAttr("aws_sns_sms_preferences.test_pref", "usage_report_s3_bucket"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAWSSNSSMSPreferences_defaultSMSType(t *testing.T) { | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckAWSSNSSMSPrefsDestroy, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testAccAWSSNSSMSPreferences_defSMSType, | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckNoResourceAttr("aws_sns_sms_preferences.test_pref", "monthly_spend_limit"), | ||
resource.TestCheckNoResourceAttr("aws_sns_sms_preferences.test_pref", "delivery_status_iam_role_arn"), | ||
resource.TestCheckNoResourceAttr("aws_sns_sms_preferences.test_pref", "delivery_status_success_sampling_rate"), | ||
resource.TestCheckNoResourceAttr("aws_sns_sms_preferences.test_pref", "default_sender_id"), | ||
resource.TestCheckResourceAttr("aws_sns_sms_preferences.test_pref", "default_sms_type", "Transactional"), | ||
resource.TestCheckNoResourceAttr("aws_sns_sms_preferences.test_pref", "usage_report_s3_bucket"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAWSSNSSMSPreferences_almostAll(t *testing.T) { | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckAWSSNSSMSPrefsDestroy, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testAccAWSSNSSMSPreferences_almostAll, | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr("aws_sns_sms_preferences.test_pref", "monthly_spend_limit", "1"), | ||
resource.TestCheckResourceAttr("aws_sns_sms_preferences.test_pref", "default_sms_type", "Transactional"), | ||
resource.TestCheckResourceAttr("aws_sns_sms_preferences.test_pref", "usage_report_s3_bucket", "some-bucket"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAWSSNSSMSPreferences_deliveryRole(t *testing.T) { | ||
arnRole := regexp.MustCompile(`^arn:aws:iam::\d+:role/test_smsdelivery_role$`) | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckAWSSNSSMSPrefsDestroy, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testAccAWSSNSSMSPreferences_deliveryRole, | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestMatchResourceAttr("aws_sns_sms_preferences.test_pref", "delivery_status_iam_role_arn", arnRole), | ||
resource.TestCheckResourceAttr("aws_sns_sms_preferences.test_pref", "delivery_status_success_sampling_rate", "75"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckAWSSNSSMSPrefsDestroy(s *terraform.State) error { | ||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "aws_sns_sms_preferences" { | ||
continue | ||
} | ||
|
||
return fmt.Errorf("SNS SMS Preferences resource exists when it should be destroyed!") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
const testAccAWSSNSSMSPreferences_empty = ` | ||
resource "aws_sns_sms_preferences" "test_pref" {} | ||
` | ||
const testAccAWSSNSSMSPreferences_defSMSType = ` | ||
resource "aws_sns_sms_preferences" "test_pref" { | ||
default_sms_type = "Transactional" | ||
} | ||
` | ||
const testAccAWSSNSSMSPreferences_almostAll = ` | ||
resource "aws_sns_sms_preferences" "test_pref" { | ||
monthly_spend_limit = "1", | ||
default_sms_type = "Transactional", | ||
usage_report_s3_bucket = "some-bucket", | ||
} | ||
` | ||
const testAccAWSSNSSMSPreferences_deliveryRole = ` | ||
resource "aws_iam_role" "test_smsdelivery_role" { | ||
name = "test_smsdelivery_role" | ||
path = "/" | ||
assume_role_policy = <<POLICY | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Action": "sts:AssumeRole", | ||
"Principal": { | ||
"Service": "sns.amazonaws.com" | ||
}, | ||
"Effect": "Allow", | ||
"Sid": "" | ||
} | ||
] | ||
} | ||
POLICY | ||
} | ||
|
||
resource "aws_iam_role_policy" "test_smsdelivery_role_policy" { | ||
name = "test_smsdelivery_role_policy" | ||
role = "${aws_iam_role.test_smsdelivery_role.id}" | ||
policy = <<POLICY | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Action": ["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents","logs:PutMetricFilter","logs:PutRetentionPolicy"], | ||
"Resource": "*", | ||
"Effect": "Allow", | ||
"Sid": "" | ||
} | ||
] | ||
} | ||
POLICY | ||
} | ||
|
||
resource "aws_sns_sms_preferences" "test_pref" { | ||
delivery_status_iam_role_arn = "${aws_iam_role.test_smsdelivery_role.arn}", | ||
delivery_status_success_sampling_rate = "75", | ||
} | ||
` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
--- | ||
layout: "aws" | ||
page_title: "AWS: sns_sms_preferences" | ||
sidebar_current: "docs-aws-resource-sns-sms-preferences" | ||
description: |- | ||
Provides a way to set SNS SMS preferences. | ||
--- | ||
|
||
# aws_sns_sms_preferences | ||
|
||
Provides a way to set SNS SMS preferences. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
resource "aws_sns_sms_preferences" "update_sms_prefs" { | ||
|
||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `monthly_spend_limit` - (Optional) The maximum amount in USD that you are willing to spend each month to send SMS messages. | ||
* `delivery_status_iam_role_arn` - (Optional) The ARN of the IAM role that allows Amazon SNS to write logs about SMS deliveries in CloudWatch Logs. | ||
* `delivery_status_success_sampling_rate` - (Optional) The percentage of successful SMS deliveries for which Amazon SNS will write logs in CloudWatch Logs. The value must be between 0 and 100. | ||
* `default_sender_id` - (Optional) A string, such as your business brand, that is displayed as the sender on the receiving device. | ||
* `default_sms_type` - (Optional) The type of SMS message that you will send by default. Possible values are: Promotional, Transactional | ||
* `usage_report_s3_bucket` - (Optional) The name of the Amazon S3 bucket to receive daily SMS usage reports from Amazon SNS. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably should be a
TypeInt
string so TF can do the proper type validationThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is tricky because the AWS API treats all those attributes as Strings, including monthly spend limit and delivery sampling rate, and an empty string "" (not defined) is not the same as a "0" (explicit 0).
Using int values in TF won't allow us to distinguish between the 2 cases and will always set those values as "0" when retrieved as "", which would be incorrect.