diff --git a/builtin/providers/aws/diff_suppress_funcs.go b/builtin/providers/aws/diff_suppress_funcs.go index 5c96c6696..e8c58b813 100644 --- a/builtin/providers/aws/diff_suppress_funcs.go +++ b/builtin/providers/aws/diff_suppress_funcs.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "log" + "net/url" "strings" "github.com/hashicorp/terraform/helper/schema" @@ -58,3 +59,19 @@ func suppressEquivalentJsonDiffs(k, old, new string, d *schema.ResourceData) boo return jsonBytesEqual(ob.Bytes(), nb.Bytes()) } + +func suppressOpenIdURL(k, old, new string, d *schema.ResourceData) bool { + oldUrl, err := url.Parse(old) + if err != nil { + return false + } + + newUrl, err := url.Parse(new) + if err != nil { + return false + } + + oldUrl.Scheme = "https" + + return oldUrl.String() == newUrl.String() +} diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index f97908772..67e813a9e 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -309,6 +309,7 @@ func Provider() terraform.ResourceProvider { "aws_iam_group_membership": resourceAwsIamGroupMembership(), "aws_iam_group_policy_attachment": resourceAwsIamGroupPolicyAttachment(), "aws_iam_instance_profile": resourceAwsIamInstanceProfile(), + "aws_iam_openid_connect_provider": resourceAwsIamOpenIDConnectProvider(), "aws_iam_policy": resourceAwsIamPolicy(), "aws_iam_policy_attachment": resourceAwsIamPolicyAttachment(), "aws_iam_role_policy_attachment": resourceAwsIamRolePolicyAttachment(), diff --git a/builtin/providers/aws/resource_aws_iam_openid_connect_provider.go b/builtin/providers/aws/resource_aws_iam_openid_connect_provider.go index cd23e86a4..fa4530fa8 100644 --- a/builtin/providers/aws/resource_aws_iam_openid_connect_provider.go +++ b/builtin/providers/aws/resource_aws_iam_openid_connect_provider.go @@ -23,10 +23,12 @@ func resourceAwsIamOpenIDConnectProvider() *schema.Resource { Computed: true, }, "url": &schema.Schema{ - Type: schema.TypeString, - Computed: false, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Computed: false, + Required: true, + ForceNew: true, + ValidateFunc: validateOpenIdURL, + DiffSuppressFunc: suppressOpenIdURL, }, "client-id-list": &schema.Schema{ Elem: &schema.Schema{Type: schema.TypeString}, diff --git a/builtin/providers/aws/validators.go b/builtin/providers/aws/validators.go index b2f934646..425a747d5 100644 --- a/builtin/providers/aws/validators.go +++ b/builtin/providers/aws/validators.go @@ -3,6 +3,7 @@ package aws import ( "fmt" "net" + "net/url" "regexp" "strings" "time" @@ -1170,3 +1171,19 @@ func validateAwsAlbTargetGroupNamePrefix(v interface{}, k string) (ws []string, } return } + +func validateOpenIdURL(v interface{}, k string) (ws []string, errors []error) { + value := v.(string) + u, err := url.Parse(value) + if err != nil { + errors = append(errors, fmt.Errorf("%q has to be a valid URL", k)) + return + } + if u.Scheme != "https" { + errors = append(errors, fmt.Errorf("%q has to use HTTPS scheme (i.e. begin with https://)", k)) + } + if len(u.Query()) > 0 { + errors = append(errors, fmt.Errorf("%q cannot contain query parameters per the OIDC standard", k)) + } + return +} diff --git a/builtin/providers/aws/validators_test.go b/builtin/providers/aws/validators_test.go index 7fe451a87..0af2b49fa 100644 --- a/builtin/providers/aws/validators_test.go +++ b/builtin/providers/aws/validators_test.go @@ -1913,3 +1913,35 @@ func TestValidateDbOptionGroupNamePrefix(t *testing.T) { } } } + +func TestValidateOpenIdURL(t *testing.T) { + cases := []struct { + Value string + ErrCount int + }{ + { + Value: "http://wrong.scheme.com", + ErrCount: 1, + }, + { + Value: "ftp://wrong.scheme.co.uk", + ErrCount: 1, + }, + { + Value: "%@invalidUrl", + ErrCount: 1, + }, + { + Value: "https://example.com/?query=param", + ErrCount: 1, + }, + } + + for _, tc := range cases { + _, errors := validateOpenIdURL(tc.Value, "url") + + if len(errors) != tc.ErrCount { + t.Fatalf("Expected %d of OpenID URL validation errors, got %d", tc.ErrCount, len(errors)) + } + } +}