Skip to content
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

d/aws_iam_openid_connect_provider #23240

Merged
merged 10 commits into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .changelog/23240.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

```release-note:new-data-source
aws_iam_openid_connect_provider
```
25 changes: 13 additions & 12 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -619,18 +619,19 @@ func Provider() *schema.Provider {

"aws_guardduty_detector": guardduty.DataSourceDetector(),

"aws_iam_account_alias": iam.DataSourceAccountAlias(),
"aws_iam_group": iam.DataSourceGroup(),
"aws_iam_instance_profile": iam.DataSourceInstanceProfile(),
"aws_iam_policy": iam.DataSourcePolicy(),
"aws_iam_policy_document": iam.DataSourcePolicyDocument(),
"aws_iam_role": iam.DataSourceRole(),
"aws_iam_roles": iam.DataSourceRoles(),
"aws_iam_server_certificate": iam.DataSourceServerCertificate(),
"aws_iam_session_context": iam.DataSourceSessionContext(),
"aws_iam_user": iam.DataSourceUser(),
"aws_iam_user_ssh_key": iam.DataSourceUserSSHKey(),
"aws_iam_users": iam.DataSourceUsers(),
"aws_iam_account_alias": iam.DataSourceAccountAlias(),
"aws_iam_group": iam.DataSourceGroup(),
"aws_iam_instance_profile": iam.DataSourceInstanceProfile(),
"aws_iam_openid_connect_provider": iam.DataSourceOpenIDConnectProvider(),
"aws_iam_policy": iam.DataSourcePolicy(),
"aws_iam_policy_document": iam.DataSourcePolicyDocument(),
"aws_iam_role": iam.DataSourceRole(),
"aws_iam_roles": iam.DataSourceRoles(),
"aws_iam_server_certificate": iam.DataSourceServerCertificate(),
"aws_iam_session_context": iam.DataSourceSessionContext(),
"aws_iam_user": iam.DataSourceUser(),
"aws_iam_user_ssh_key": iam.DataSourceUserSSHKey(),
"aws_iam_users": iam.DataSourceUsers(),

"aws_identitystore_group": identitystore.DataSourceGroup(),
"aws_identitystore_user": identitystore.DataSourceUser(),
Expand Down
10 changes: 10 additions & 0 deletions internal/service/iam/find.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package iam

import (
"fmt"
"regexp"
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/iam"
Expand Down Expand Up @@ -280,3 +282,11 @@ func FindSigningCertificate(conn *iam.IAM, userName, certId string) (*iam.Signin

return cert, nil
}

func urlFromOpenIDConnectProviderArn(arn string) (string, error) {
parts := strings.SplitN(arn, "/", 2)
if len(parts) != 2 {
return "", fmt.Errorf("error reading OpenID Connect Provider expected the arn to be like: arn:PARTITION:iam::ACCOUNT:oidc-provider/URL but got: %s", arn)
}
return parts[1], nil
}
120 changes: 120 additions & 0 deletions internal/service/iam/openid_connect_provider_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package iam

import (
"context"
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/flex"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
)

func DataSourceOpenIDConnectProvider() *schema.Resource {
return &schema.Resource{
ReadWithoutTimeout: dataSourceOpenIDConnectProviderRead,

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: verify.ValidARN,
ExactlyOneOf: []string{"arn", "url"},
},
"client_id_list": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"thumbprint_list": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"tags": tftags.TagsSchemaComputed(),
"url": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validOpenIDURL,
DiffSuppressFunc: suppressOpenIDURL,
ExactlyOneOf: []string{"arn", "url"},
},
},
}
}

func dataSourceOpenIDConnectProviderRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).IAMConn
ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig

input := &iam.GetOpenIDConnectProviderInput{}

if v, ok := d.GetOk("arn"); ok {
input.OpenIDConnectProviderArn = aws.String(v.(string))
} else if v, ok := d.GetOk("url"); ok {
url := v.(string)

oidcpEntry, err := dataSourceGetOpenIDConnectProviderByURL(ctx, conn, url)
if err != nil {
return diag.Errorf("error finding IAM OIDC Provider by url (%s): %s", url, err)
}

if oidcpEntry == nil {
return diag.Errorf("error finding IAM OIDC Provider by url (%s): not found", url)
}
input.OpenIDConnectProviderArn = oidcpEntry.Arn
}

resp, err := conn.GetOpenIDConnectProviderWithContext(ctx, input)

if err != nil {
return diag.Errorf("error reading IAM OIDC Provider: %s", err)
}

d.SetId(aws.StringValue(input.OpenIDConnectProviderArn))
d.Set("arn", input.OpenIDConnectProviderArn)
d.Set("url", resp.Url)
d.Set("client_id_list", flex.FlattenStringList(resp.ClientIDList))
d.Set("thumbprint_list", flex.FlattenStringList(resp.ThumbprintList))

if err := d.Set("tags", KeyValueTags(resp.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
return diag.Errorf("error setting tags: %s", err)
}

return nil
}

func dataSourceGetOpenIDConnectProviderByURL(ctx context.Context, conn *iam.IAM, url string) (*iam.OpenIDConnectProviderListEntry, error) {
var result *iam.OpenIDConnectProviderListEntry

input := &iam.ListOpenIDConnectProvidersInput{}

output, err := conn.ListOpenIDConnectProvidersWithContext(ctx, input)

if err != nil {
return nil, err
}

for _, oidcp := range output.OpenIDConnectProviderList {
if oidcp == nil {
continue
}

arnUrl, err := urlFromOpenIDConnectProviderArn(aws.StringValue(oidcp.Arn))
if err != nil {
return nil, err
}

if arnUrl == strings.TrimPrefix(url, "https://") {
return oidcp, nil
}
}

return result, nil
}
149 changes: 149 additions & 0 deletions internal/service/iam/openid_connect_provider_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package iam_test

import (
"fmt"
"testing"

"github.com/aws/aws-sdk-go/service/iam"
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
)

func TestAccIAMOpenidConnectProviderDataSource_basic(t *testing.T) {
rString := sdkacctest.RandString(5)
dataSourceName := "data.aws_iam_openid_connect_provider.test"
resourceName := "aws_iam_openid_connect_provider.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, iam.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckIAMOpenIDConnectProviderDestroy,
Steps: []resource.TestStep{
{
Config: testAccIAMOpenIDConnectProviderDataSourceConfig_basic(rString),
Check: resource.ComposeTestCheckFunc(
testAccCheckIAMOpenIDConnectProvider(resourceName),
resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "url", resourceName, "url"),
resource.TestCheckResourceAttrPair(dataSourceName, "client_id_list", resourceName, "client_id_list"),
resource.TestCheckResourceAttrPair(dataSourceName, "thumbprint_list", resourceName, "thumbprint_list"),
resource.TestCheckResourceAttr(resourceName, "tags.%", "0"),
),
},
},
})
}

func TestAccIAMOpenidConnectProviderDataSource_url(t *testing.T) {
rString := sdkacctest.RandString(5)
dataSourceName := "data.aws_iam_openid_connect_provider.test"
resourceName := "aws_iam_openid_connect_provider.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, iam.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckIAMOpenIDConnectProviderDestroy,
Steps: []resource.TestStep{
{
Config: testAccIAMOpenIDConnectProviderDataSourceConfig_url(rString),
Check: resource.ComposeTestCheckFunc(
testAccCheckIAMOpenIDConnectProvider(resourceName),
resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "url", resourceName, "url"),
resource.TestCheckResourceAttrPair(dataSourceName, "client_id_list", resourceName, "client_id_list"),
resource.TestCheckResourceAttrPair(dataSourceName, "thumbprint_list", resourceName, "thumbprint_list"),
resource.TestCheckResourceAttr(resourceName, "tags.%", "0"),
),
},
},
})
}

func TestAccIAMOpenidConnectProviderDataSource_tags(t *testing.T) {
rString := sdkacctest.RandString(5)
dataSourceName := "data.aws_iam_openid_connect_provider.test"
resourceName := "aws_iam_openid_connect_provider.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, iam.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckIAMOpenIDConnectProviderDestroy,
Steps: []resource.TestStep{
{
Config: testAccIAMOpenIDConnectProviderDataSourceConfig_tags(rString),
Check: resource.ComposeTestCheckFunc(
testAccCheckIAMOpenIDConnectProvider(resourceName),
resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "url", resourceName, "url"),
resource.TestCheckResourceAttrPair(dataSourceName, "client_id_list", resourceName, "client_id_list"),
resource.TestCheckResourceAttrPair(dataSourceName, "thumbprint_list", resourceName, "thumbprint_list"),
resource.TestCheckResourceAttr(dataSourceName, "tags.%", "2"),
resource.TestCheckResourceAttr(dataSourceName, "tags.tag1", "test-value1"),
resource.TestCheckResourceAttr(dataSourceName, "tags.tag2", "test-value2")),
},
},
})
}

func testAccIAMOpenIDConnectProviderDataSourceConfig_basic(rString string) string {
return fmt.Sprintf(`
resource "aws_iam_openid_connect_provider" "test" {
url = "https://accounts.testle.com/%s"

client_id_list = [
"266362248691-re108qaeld573ia0l6clj2i5ac7r7291.apps.testleusercontent.com",
]

thumbprint_list = []
}

data "aws_iam_openid_connect_provider" "test" {
arn = aws_iam_openid_connect_provider.test.arn
}
`, rString)
}

func testAccIAMOpenIDConnectProviderDataSourceConfig_url(rString string) string {
return fmt.Sprintf(`
resource "aws_iam_openid_connect_provider" "test" {
url = "https://accounts.testle.com/%s"

client_id_list = [
"266362248691-re108qaeld573ia0l6clj2i5ac7r7291.apps.testleusercontent.com",
]

thumbprint_list = []
}

data "aws_iam_openid_connect_provider" "test" {
url = "https://${aws_iam_openid_connect_provider.test.url}"
}
`, rString)
}

func testAccIAMOpenIDConnectProviderDataSourceConfig_tags(rString string) string {
return fmt.Sprintf(`
resource "aws_iam_openid_connect_provider" "test" {
url = "https://accounts.testle.com/%s"

client_id_list = [
"266362248691-re108qaeld573ia0l6clj2i5ac7r7291.apps.testleusercontent.com",
]

thumbprint_list = []

tags = {
tag1 = "test-value1"
tag2 = "test-value2"
}
}

data "aws_iam_openid_connect_provider" "test" {
arn = aws_iam_openid_connect_provider.test.arn
}
`, rString)
}
39 changes: 39 additions & 0 deletions website/docs/d/iam_openid_connect_provider.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
subcategory: "IAM"
layout: "aws"
page_title: "AWS: aws_iam_openid_connect_provider"
description: |-
Get information on a Amazon IAM OpenID Connect provider.
---

# Data Source: aws_iam_openid_connect_provider

This data source can be used to fetch information about a specific
IAM OpenID Connect provider. By using this data source, you can retrieve the
the resource information by either its `arn` or `url`.

## Example Usage

```terraform
data "aws_iam_openid_connect_provider" "example" {
arn = "arn:aws:iam::123456789012:oidc-provider/accounts.google.com"
}
```

```terraform
data "aws_iam_openid_connect_provider" "example" {
url = "https://accounts.google.com"
}
```

## Argument Reference

* `arn` - (Optional) The Amazon Resource Name (ARN) specifying the OpenID Connect provider.

* `url` - (Optional) The URL of the OpenID Connect provider.

## Attributes Reference

* `client_id_list` - A list of client IDs (also known as audiences). When a mobile or web app registers with an OpenID Connect provider, they establish a value that identifies the application. (This is the value that's sent as the client_id parameter on OAuth requests.)
* `thumbprint_list` - A list of server certificate thumbprints for the OpenID Connect (OIDC) identity provider's server certificate(s).
* `tags` - Map of resource tags for the IAM OIDC provider.