diff --git a/aws/resource_aws_cognito_user_pool.go b/aws/resource_aws_cognito_user_pool.go index 33c417f1238..051483a6558 100644 --- a/aws/resource_aws_cognito_user_pool.go +++ b/aws/resource_aws_cognito_user_pool.go @@ -412,6 +412,25 @@ func resourceAwsCognitoUserPool() *schema.Resource { ConflictsWith: []string{"alias_attributes"}, }, + "user_pool_add_ons": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "advanced_security_mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + cognitoidentityprovider.AdvancedSecurityModeTypeAudit, + cognitoidentityprovider.AdvancedSecurityModeTypeEnforced, + cognitoidentityprovider.AdvancedSecurityModeTypeOff, + }, false), + }, + }, + }, + }, + "verification_message_template": { Type: schema.TypeList, Optional: true, @@ -580,6 +599,20 @@ func resourceAwsCognitoUserPoolCreate(d *schema.ResourceData, meta interface{}) params.UsernameAttributes = expandStringList(v.([]interface{})) } + if v, ok := d.GetOk("user_pool_add_ons"); ok { + configs := v.([]interface{}) + config, ok := configs[0].(map[string]interface{}) + + if ok { + userPoolAddons := &cognitoidentityprovider.UserPoolAddOnsType{} + + if v, ok := config["advanced_security_mode"]; ok && v.(string) != "" { + userPoolAddons.AdvancedSecurityMode = aws.String(v.(string)) + } + params.UserPoolAddOns = userPoolAddons + } + } + if v, ok := d.GetOk("verification_message_template"); ok { configs := v.([]interface{}) config, ok := configs[0].(map[string]interface{}) @@ -710,6 +743,10 @@ func resourceAwsCognitoUserPoolRead(d *schema.ResourceData, meta interface{}) er d.Set("username_attributes", flattenStringList(resp.UserPool.UsernameAttributes)) } + if err := d.Set("user_pool_add_ons", flattenCognitoUserPoolUserPoolAddOns(resp.UserPool.UserPoolAddOns)); err != nil { + return fmt.Errorf("Failed setting user_pool_add_ons: %s", err) + } + if err := d.Set("verification_message_template", flattenCognitoUserPoolVerificationMessageTemplate(resp.UserPool.VerificationMessageTemplate)); err != nil { return fmt.Errorf("Failed setting verification_message_template: %s", err) } @@ -815,6 +852,20 @@ func resourceAwsCognitoUserPoolUpdate(d *schema.ResourceData, meta interface{}) } } + if v, ok := d.GetOk("user_pool_add_ons"); ok { + configs := v.([]interface{}) + config, ok := configs[0].(map[string]interface{}) + + if ok && config != nil { + userPoolAddons := &cognitoidentityprovider.UserPoolAddOnsType{} + + if v, ok := config["advanced_security_mode"]; ok && v.(string) != "" { + userPoolAddons.AdvancedSecurityMode = aws.String(v.(string)) + } + params.UserPoolAddOns = userPoolAddons + } + } + if v, ok := d.GetOk("verification_message_template"); ok { configs := v.([]interface{}) config, ok := configs[0].(map[string]interface{}) diff --git a/aws/resource_aws_cognito_user_pool_test.go b/aws/resource_aws_cognito_user_pool_test.go index 06992b1a552..b95c29ec61d 100644 --- a/aws/resource_aws_cognito_user_pool_test.go +++ b/aws/resource_aws_cognito_user_pool_test.go @@ -153,6 +153,37 @@ func TestAccAWSCognitoUserPool_withAdminCreateUserConfiguration(t *testing.T) { }) } +func TestAccAWSCognitoUserPool_withAdvancedSecurityMode(t *testing.T) { + name := acctest.RandString(5) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCognitoUserPoolDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCognitoUserPoolConfig_withAdvancedSecurityMode(name, "OFF"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSCognitoUserPoolExists("aws_cognito_user_pool.pool"), + resource.TestCheckResourceAttr("aws_cognito_user_pool.pool", "user_pool_add_ons.0.advanced_security_mode", "OFF"), + ), + }, + { + Config: testAccAWSCognitoUserPoolConfig_withAdvancedSecurityMode(name, "ENFORCED"), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aws_cognito_user_pool.pool", "user_pool_add_ons.0.advanced_security_mode", "ENFORCED"), + ), + }, + { + Config: testAccAWSCognitoUserPoolConfig_basic(name), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aws_cognito_user_pool.pool", "user_pool_add_ons.#", "0"), + ), + }, + }, + }) +} + func TestAccAWSCognitoUserPool_withDeviceConfiguration(t *testing.T) { name := acctest.RandString(5) @@ -736,6 +767,17 @@ resource "aws_cognito_user_pool" "pool" { }`, name) } +func testAccAWSCognitoUserPoolConfig_withAdvancedSecurityMode(name string, mode string) string { + return fmt.Sprintf(` +resource "aws_cognito_user_pool" "pool" { + name = "terraform-test-pool-%s" + + user_pool_add_ons { + advanced_security_mode = "%s" + } +}`, name, mode) +} + func testAccAWSCognitoUserPoolConfig_withDeviceConfiguration(name string) string { return fmt.Sprintf(` resource "aws_cognito_user_pool" "pool" { diff --git a/aws/structure.go b/aws/structure.go index 1a2449e827d..d8a57fe05c6 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -2781,6 +2781,20 @@ func expandCognitoUserPoolPasswordPolicy(config map[string]interface{}) *cognito return configs } +func flattenCognitoUserPoolUserPoolAddOns(s *cognitoidentityprovider.UserPoolAddOnsType) []map[string]interface{} { + config := make(map[string]interface{}) + + if s == nil { + return []map[string]interface{}{} + } + + if s.AdvancedSecurityMode != nil { + config["advanced_security_mode"] = *s.AdvancedSecurityMode + } + + return []map[string]interface{}{config} +} + func flattenIoTRuleCloudWatchAlarmActions(actions []*iot.Action) []map[string]interface{} { results := make([]map[string]interface{}, 0) diff --git a/website/docs/r/cognito_user_pool.markdown b/website/docs/r/cognito_user_pool.markdown index dd48a1ca3cf..5a45074a024 100644 --- a/website/docs/r/cognito_user_pool.markdown +++ b/website/docs/r/cognito_user_pool.markdown @@ -41,6 +41,7 @@ The following arguments are supported: * `sms_verification_message` - (Optional) A string representing the SMS verification message. * `tags` - (Optional) A mapping of tags to assign to the User Pool. * `username_attributes` - (Optional) Specifies whether email addresses or phone numbers can be specified as usernames when a user signs up. Conflicts with `alias_attributes`. +* `user_pool_add_ons` - (Optional) Configuration block for [user pool add-ons](#user-pool-add-ons) to enable user pool advanced security mode features. * `verification_message_template` (Optional) - The [verification message templates](#verification-message-template) configuration. #### Admin Create User Config @@ -111,6 +112,10 @@ The following arguments are supported: * `external_id` (Required) - The external ID used in IAM role trust relationships. For more information about using external IDs, see [How to Use an External ID When Granting Access to Your AWS Resources to a Third Party](http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html). * `sns_caller_arn` (Required) - The ARN of the Amazon SNS caller. This is usually the IAM role that you've given Cognito permission to assume. +#### User Pool Add-ons + + * `advanced_security_mode` (Required) - The mode for advanced security, must be one of `OFF`, `AUDIT` or `ENFORCED`. + #### Verification Message Template * `default_email_option` (Optional) - The default email option. Must be either `CONFIRM_WITH_CODE` or `CONFIRM_WITH_LINK`. Defaults to `CONFIRM_WITH_CODE`.