From 8c52fe19f0bde205dadf24c929f81f1d37fac576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Socha?= Date: Fri, 2 Mar 2018 15:49:12 +0100 Subject: [PATCH 1/5] Start work on new resource aws_cognito_identity_provider --- aws/provider.go | 1 + 1 file changed, 1 insertion(+) diff --git a/aws/provider.go b/aws/provider.go index 6aa0203b3acd..a77b4ee93f28 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -304,6 +304,7 @@ func Provider() terraform.ResourceProvider { "aws_config_delivery_channel": resourceAwsConfigDeliveryChannel(), "aws_cognito_identity_pool": resourceAwsCognitoIdentityPool(), "aws_cognito_identity_pool_roles_attachment": resourceAwsCognitoIdentityPoolRolesAttachment(), + "aws_cognito_identity_provider": resourceAwsCognitoIdentityProvider(), "aws_cognito_user_group": resourceAwsCognitoUserGroup(), "aws_cognito_user_pool": resourceAwsCognitoUserPool(), "aws_cognito_user_pool_client": resourceAwsCognitoUserPoolClient(), From 7756cf2549ddba225e8353054ee104332cf9b4b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Socha?= Date: Tue, 6 Mar 2018 10:31:53 +0100 Subject: [PATCH 2/5] Add code --- aws/resource_aws_cognito_identity_provider.go | 185 ++++++++++++++++++ ...urce_aws_cognito_identity_provider_test.go | 81 ++++++++ aws/structure.go | 17 ++ 3 files changed, 283 insertions(+) create mode 100644 aws/resource_aws_cognito_identity_provider.go create mode 100644 aws/resource_aws_cognito_identity_provider_test.go diff --git a/aws/resource_aws_cognito_identity_provider.go b/aws/resource_aws_cognito_identity_provider.go new file mode 100644 index 000000000000..806bc3851cb6 --- /dev/null +++ b/aws/resource_aws_cognito_identity_provider.go @@ -0,0 +1,185 @@ +package aws + +import ( + "fmt" + "log" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAwsCognitoIdentityProvider() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsCognitoIdentityProviderCreate, + Read: resourceAwsCognitoIdentityProviderRead, + Update: resourceAwsCognitoIdentityProviderUpdate, + Delete: resourceAwsCognitoIdentityProviderDelete, + + Timeouts: &schema.ResourceTimeout{ + Delete: schema.DefaultTimeout(5 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "attribute_mapping": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "idp_identifiers": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "provider_details": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "provider_name": { + Type: schema.TypeString, + Required: true, + }, + + "provider_type": { + Type: schema.TypeString, + Required: true, + }, + + "user_pool_id": { + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func resourceAwsCognitoIdentityProviderCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cognitoidpconn + log.Print("[DEBUG] Creating Cognito Identity Provider") + + name := aws.String(d.Get("provider_name").(string)) + params := &cognitoidentityprovider.CreateIdentityProviderInput{ + ProviderName: name, + ProviderType: aws.String(d.Get("provider_type").(string)), + UserPoolId: aws.String(d.Get("user_pool_id").(string)), + } + + if v, ok := d.GetOk("attribute_mapping"); ok { + params.AttributeMapping = expandCognitoIdentityProviderMap(v.(map[string]interface{})) + } + + if v, ok := d.GetOk("provider_details"); ok { + params.ProviderDetails = expandCognitoIdentityProviderMap(v.(map[string]interface{})) + } + + if v, ok := d.GetOk("idp_identifiers"); ok { + params.IdpIdentifiers = expandStringList(v.([]interface{})) + } + + _, err := conn.CreateIdentityProvider(params) + if err != nil { + return fmt.Errorf("Error creating Cognito Identity Provider: %s", err) + } + + d.SetId(*name) + + return resourceAwsCognitoIdentityProviderRead(d, meta) +} + +func resourceAwsCognitoIdentityProviderRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cognitoidpconn + log.Printf("[DEBUG] Reading Cognito Identity Provider: %s", d.Id()) + + ret, err := conn.DescribeIdentityProvider(&cognitoidentityprovider.DescribeIdentityProviderInput{ + ProviderName: aws.String(d.Id()), + UserPoolId: aws.String(d.Get("user_pool_id").(string)), + }) + + if err != nil { + if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "ResourceNotFoundException" { + d.SetId("") + return nil + } + return err + } + + ip := ret.IdentityProvider + d.Set("provider_name", ip.ProviderName) + d.Set("provider_type", ip.ProviderType) + d.Set("user_pool_id", ip.UserPoolId) + + if err := d.Set("attribute_mapping", flattenCognitoIdentityProviderMap(ip.AttributeMapping)); err != nil { + return fmt.Errorf("[DEBUG] Error setting attribute_mapping error: %#v", err) + } + + if err := d.Set("provider_details", flattenCognitoIdentityProviderMap(ip.ProviderDetails)); err != nil { + return fmt.Errorf("[DEBUG] Error setting provider_details error: %#v", err) + } + + if err := d.Set("idp_identifiers", flattenStringList(ip.IdpIdentifiers)); err != nil { + return fmt.Errorf("[DEBUG] Error setting idp_identifiers error: %#v", err) + } + + return nil +} + +func resourceAwsCognitoIdentityProviderUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cognitoidpconn + log.Print("[DEBUG] Updating Cognito Identity Provider") + + params := &cognitoidentityprovider.UpdateIdentityProviderInput{ + UserPoolId: aws.String(d.Get("UserPoolId").(string)), + ProviderName: aws.String(d.Id()), + } + + if d.HasChange("attribute_mapping") { + params.AttributeMapping = expandCognitoIdentityProviderMap(d.Get("attribute_mapping").(map[string]interface{})) + } + + if d.HasChange("provider_details") { + params.ProviderDetails = expandCognitoIdentityProviderMap(d.Get("provider_details").(map[string]interface{})) + } + + if d.HasChange("idp_identifiers") { + params.IdpIdentifiers = expandStringList(d.Get("supported_login_providers").([]interface{})) + } + + _, err := conn.UpdateIdentityProvider(params) + if err != nil { + return fmt.Errorf("Error updating Cognito Identity Provider: %s", err) + } + + return resourceAwsCognitoIdentityProviderRead(d, meta) +} + +func resourceAwsCognitoIdentityProviderDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cognitoidpconn + log.Printf("[DEBUG] Deleting Cognito Identity Provider: %s", d.Id()) + + return resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { + _, err := conn.DeleteIdentityProvider(&cognitoidentityprovider.DeleteIdentityProviderInput{ + ProviderName: aws.String(d.Id()), + UserPoolId: aws.String(d.Get("user_pool_id").(string)), + }) + + if err == nil { + d.SetId("") + return nil + } + + return resource.NonRetryableError(err) + }) +} diff --git a/aws/resource_aws_cognito_identity_provider_test.go b/aws/resource_aws_cognito_identity_provider_test.go new file mode 100644 index 000000000000..52e6fd9885c7 --- /dev/null +++ b/aws/resource_aws_cognito_identity_provider_test.go @@ -0,0 +1,81 @@ +package aws + +import ( + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAWSCognitoIdentityProvider_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCognitoIdentityProviderDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCognitoIdentityProviderConfig_basic(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_name", "gprovider"), + ), + }, + }, + }) +} + +func testAccCheckAWSCognitoIdentityProviderDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).cognitoidpconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_cognito_identity_provider" { + continue + } + + _, err := conn.DescribeIdentityProvider(&cognitoidentityprovider.DescribeIdentityProviderInput{ + ProviderName: aws.String(rs.Primary.ID), + UserPoolId: aws.String(rs.Primary.Attributes["user_pool_id"]), + }) + + if err != nil { + if wserr, ok := err.(awserr.Error); ok && wserr.Code() == "ResourceNotFoundException" { + return nil + } + return err + } + } + + return nil +} + +func testAccAWSCognitoIdentityProviderConfig_basic() string { + return ` + +resource "aws_cognito_user_pool" "tf_test_pool" { + name = "tfmytestpool" + auto_verified_attributes = ["email"] +} + +resource "aws_cognito_identity_provider" "tf_test_provider" { + user_pool_id = "${aws_cognito_user_pool.tf_test_pool.id}" + provider_name = "gprovider" + provider_type = "Google" + + provider_details { + attributes_url = "https://people.googleapis.com/v1/people/me?personFields=" + authorize_scopes = "email" + token_request_method = "POST" + token_url = "https://www.googleapis.com/oauth2/v4/token" + client_id = "239432985801-nq4c0l7cdpa16sa2cnlvr5mcgdt0gkug.apps.googleusercontent.com" + client_secret = "client_secret" + } + + attribute_mapping { + email = "email" + username = "sub" + } +} +` +} diff --git a/aws/structure.go b/aws/structure.go index 39a0ad00db58..ad8c68fdcd22 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -3035,6 +3035,23 @@ func flattenCognitoIdentityPoolRoles(config map[string]*string) map[string]strin return m } +func expandCognitoIdentityProviderMap(config map[string]interface{}) map[string]*string { + m := map[string]*string{} + for k, v := range config { + s := v.(string) + m[k] = &s + } + return m +} + +func flattenCognitoIdentityProviderMap(config map[string]*string) map[string]string { + m := map[string]string{} + for k, v := range config { + m[k] = *v + } + return m +} + func expandCognitoIdentityPoolRoleMappingsAttachment(rms []interface{}) map[string]*cognitoidentity.RoleMapping { values := make(map[string]*cognitoidentity.RoleMapping, 0) From a8b5a3d19619f2c0a6f7f128b824eb6244f24500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Socha?= Date: Tue, 6 Mar 2018 11:47:16 +0100 Subject: [PATCH 3/5] Add documentation --- .../r/cognito_identity_provider.html.markdown | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 website/docs/r/cognito_identity_provider.html.markdown diff --git a/website/docs/r/cognito_identity_provider.html.markdown b/website/docs/r/cognito_identity_provider.html.markdown new file mode 100644 index 000000000000..86969b29bea1 --- /dev/null +++ b/website/docs/r/cognito_identity_provider.html.markdown @@ -0,0 +1,51 @@ +--- +layout: "aws" +page_title: "AWS: aws_cognito_identity_provider" +side_bar_current: "docs-aws-resource-cognito-identity-provider" +description: |- + Provides a Cognito User Identity Provider resource. +--- + +# aws_cognito_identity_provider + +Provides a Cognito User Identity Provider resource. + +## Example Usage + +### Basic configuration + +```hcl +resource "aws_cognito_user_pool" "example" { + name = "example-pool" + auto_verified_attributes = ["email"] +} + +resource "aws_cognito_identity_provider" "example_provider" { + user_pool_id = "${aws_cognito_user_pool.example.id}" + provider_name = "example_name" + provider_type = "Google" + + provider_details { + authorize_scopes = "email" + client_id = "your client_id" + client_secret = "your client_secret" + } + + attribute_mapping { + email = "email" + username = "sub" + } +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `user_pool_id` (Required) - The user pool id +* `provider_name` (Required) - The provider name +* `provider_type` (Required) - The provider type. [See AWS API for valid values](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateIdentityProvider.html#CognitoUserPools-CreateIdentityProvider-request-ProviderType) +* `attribute_mapping` (Optional) - The map of attribute mapping of user pool attributes. [AttributeMapping in AWS API documentation](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateIdentityProvider.html#CognitoUserPools-CreateIdentityProvider-request-AttributeMapping) +* `idp_identifiers` (Optional) - The list of identity providers. +* `provider_details` (Optional) - The map of identity details, sucha as access token From 17ac7cc9b41c78bfa64080f344235c54774a7dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Socha?= Date: Wed, 7 Mar 2018 23:51:47 +0100 Subject: [PATCH 4/5] Cleanup code, add extra tests, fix typos in manual --- aws/resource_aws_cognito_identity_provider.go | 7 +---- ...urce_aws_cognito_identity_provider_test.go | 26 ++++++++++++++----- .../r/cognito_identity_provider.html.markdown | 8 +++++- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/aws/resource_aws_cognito_identity_provider.go b/aws/resource_aws_cognito_identity_provider.go index 806bc3851cb6..3e9a8b6be211 100644 --- a/aws/resource_aws_cognito_identity_provider.go +++ b/aws/resource_aws_cognito_identity_provider.go @@ -27,9 +27,6 @@ func resourceAwsCognitoIdentityProvider() *schema.Resource { "attribute_mapping": { Type: schema.TypeMap, Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, }, "idp_identifiers": { @@ -43,9 +40,7 @@ func resourceAwsCognitoIdentityProvider() *schema.Resource { "provider_details": { Type: schema.TypeMap, Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, + Computed: true, }, "provider_name": { diff --git a/aws/resource_aws_cognito_identity_provider_test.go b/aws/resource_aws_cognito_identity_provider_test.go index 52e6fd9885c7..4e4cd86df1a1 100644 --- a/aws/resource_aws_cognito_identity_provider_test.go +++ b/aws/resource_aws_cognito_identity_provider_test.go @@ -19,7 +19,18 @@ func TestAccAWSCognitoIdentityProvider_basic(t *testing.T) { { Config: testAccAWSCognitoIdentityProviderConfig_basic(), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_name", "gprovider"), + resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_name", "Google"), + resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_type", "Google"), + resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_details.%", "9"), + resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_details.authorize_scopes", "email"), + resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_details.authorize_url", "https://accounts.google.com/o/oauth2/v2/auth"), + resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_details.client_id", "test-url.apps.googleusercontent.com"), + resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_details.client_secret", "client_secret"), + resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_details.attributes_url", "https://people.googleapis.com/v1/people/me?personFields="), + resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_details.attributes_url_add_attributes", "true"), + resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_details.token_request_method", "POST"), + resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_details.token_url", "https://www.googleapis.com/oauth2/v4/token"), + resource.TestCheckResourceAttr("aws_cognito_identity_provider.tf_test_provider", "provider_details.oidc_issuer", "https://accounts.google.com"), ), }, }, @@ -60,16 +71,19 @@ resource "aws_cognito_user_pool" "tf_test_pool" { resource "aws_cognito_identity_provider" "tf_test_provider" { user_pool_id = "${aws_cognito_user_pool.tf_test_pool.id}" - provider_name = "gprovider" + provider_name = "Google" provider_type = "Google" provider_details { - attributes_url = "https://people.googleapis.com/v1/people/me?personFields=" authorize_scopes = "email" - token_request_method = "POST" - token_url = "https://www.googleapis.com/oauth2/v4/token" - client_id = "239432985801-nq4c0l7cdpa16sa2cnlvr5mcgdt0gkug.apps.googleusercontent.com" + client_id = "test-url.apps.googleusercontent.com" client_secret = "client_secret" + attributes_url = "https://people.googleapis.com/v1/people/me?personFields=" + attributes_url_add_attributes = "true" + authorize_url = "https://accounts.google.com/o/oauth2/v2/auth" + oidc_issuer = "https://accounts.google.com" + token_request_method = "POST" + token_url = "https://www.googleapis.com/oauth2/v4/token" } attribute_mapping { diff --git a/website/docs/r/cognito_identity_provider.html.markdown b/website/docs/r/cognito_identity_provider.html.markdown index 86969b29bea1..338c46f5c5be 100644 --- a/website/docs/r/cognito_identity_provider.html.markdown +++ b/website/docs/r/cognito_identity_provider.html.markdown @@ -48,4 +48,10 @@ The following arguments are supported: * `provider_type` (Required) - The provider type. [See AWS API for valid values](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateIdentityProvider.html#CognitoUserPools-CreateIdentityProvider-request-ProviderType) * `attribute_mapping` (Optional) - The map of attribute mapping of user pool attributes. [AttributeMapping in AWS API documentation](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateIdentityProvider.html#CognitoUserPools-CreateIdentityProvider-request-AttributeMapping) * `idp_identifiers` (Optional) - The list of identity providers. -* `provider_details` (Optional) - The map of identity details, sucha as access token +* `provider_details` (Optional) - The map of identity details, such as access token + +## Timeouts + +`aws_cognito_identity_provider` provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: +- `delete` - (Default `5 minutes`) Used for provider deletion From e0bc3294859a0f1eebc81127308ea78b80434597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Socha?= Date: Fri, 4 May 2018 21:49:29 +0200 Subject: [PATCH 5/5] Accoring to ldenman comment: fix Get with wrong variable name, add ForceNew to user_pool_id --- aws/resource_aws_cognito_identity_provider.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_cognito_identity_provider.go b/aws/resource_aws_cognito_identity_provider.go index 3e9a8b6be211..87cb50f4ba1a 100644 --- a/aws/resource_aws_cognito_identity_provider.go +++ b/aws/resource_aws_cognito_identity_provider.go @@ -56,6 +56,7 @@ func resourceAwsCognitoIdentityProvider() *schema.Resource { "user_pool_id": { Type: schema.TypeString, Required: true, + ForceNew: true, }, }, } @@ -136,7 +137,7 @@ func resourceAwsCognitoIdentityProviderUpdate(d *schema.ResourceData, meta inter log.Print("[DEBUG] Updating Cognito Identity Provider") params := &cognitoidentityprovider.UpdateIdentityProviderInput{ - UserPoolId: aws.String(d.Get("UserPoolId").(string)), + UserPoolId: aws.String(d.Get("user_pool_id").(string)), ProviderName: aws.String(d.Id()), }