diff --git a/cloudflare/resource_cloudflare_access_application.go b/cloudflare/resource_cloudflare_access_application.go index 62a295fed5..3a29ab6937 100644 --- a/cloudflare/resource_cloudflare_access_application.go +++ b/cloudflare/resource_cloudflare_access_application.go @@ -98,6 +98,13 @@ func resourceCloudflareAccessApplication() *schema.Resource { Optional: true, Default: false, }, + "allowed_idps": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, }, } } @@ -105,6 +112,7 @@ func resourceCloudflareAccessApplication() *schema.Resource { func resourceCloudflareAccessApplicationCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*cloudflare.API) zoneID := d.Get("zone_id").(string) + allowedIDPList := expandInterfaceToStringList(d.Get("allowed_idps")) newAccessApplication := cloudflare.AccessApplication{ Name: d.Get("name").(string), @@ -113,6 +121,10 @@ func resourceCloudflareAccessApplicationCreate(d *schema.ResourceData, meta inte AutoRedirectToIdentity: d.Get("auto_redirect_to_identity").(bool), } + if len(allowedIDPList) > 0 { + newAccessApplication.AllowedIdps = allowedIDPList + } + if _, ok := d.GetOk("cors_headers"); ok { CORSConfig, _ := convertCORSSchemaToStruct(d) newAccessApplication.CorsHeaders = CORSConfig @@ -148,6 +160,7 @@ func resourceCloudflareAccessApplicationRead(d *schema.ResourceData, meta interf d.Set("session_duration", accessApplication.SessionDuration) d.Set("domain", accessApplication.Domain) d.Set("auto_redirect_to_identity", accessApplication.AutoRedirectToIdentity) + d.Set("allowed_idps", accessApplication.AllowedIdps) corsConfig := convertCORSStructToSchema(d, accessApplication.CorsHeaders) if corsConfigErr := d.Set("cors_headers", corsConfig); corsConfigErr != nil { @@ -160,6 +173,7 @@ func resourceCloudflareAccessApplicationRead(d *schema.ResourceData, meta interf func resourceCloudflareAccessApplicationUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*cloudflare.API) zoneID := d.Get("zone_id").(string) + allowedIDPList := expandInterfaceToStringList(d.Get("allowed_idps")) updatedAccessApplication := cloudflare.AccessApplication{ ID: d.Id(), @@ -169,6 +183,10 @@ func resourceCloudflareAccessApplicationUpdate(d *schema.ResourceData, meta inte AutoRedirectToIdentity: d.Get("auto_redirect_to_identity").(bool), } + if len(allowedIDPList) > 0 { + updatedAccessApplication.AllowedIdps = allowedIDPList + } + if _, ok := d.GetOk("cors_headers"); ok { CORSConfig, _ := convertCORSSchemaToStruct(d) updatedAccessApplication.CorsHeaders = CORSConfig diff --git a/cloudflare/resource_cloudflare_access_application_test.go b/cloudflare/resource_cloudflare_access_application_test.go index 9627453847..9e74284dff 100644 --- a/cloudflare/resource_cloudflare_access_application_test.go +++ b/cloudflare/resource_cloudflare_access_application_test.go @@ -95,6 +95,33 @@ func TestAccCloudflareAccessApplicationWithAutoRedirectToIdentity(t *testing.T) }) } +func TestAccCloudflareAccessApplicationWithADefinedIdps(t *testing.T) { + accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID") + rnd := generateRandomResourceName() + name := fmt.Sprintf("cloudflare_access_application.%s", rnd) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudflareAccessApplicationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCloudflareAccessApplicationConfigWithADefinedIdp(rnd, zoneID, domain, accountID), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(name, "zone_id", zoneID), + resource.TestCheckResourceAttr(name, "name", rnd), + resource.TestCheckResourceAttr(name, "domain", fmt.Sprintf("%s.%s", rnd, domain)), + resource.TestCheckResourceAttr(name, "session_duration", "24h"), + resource.TestCheckResourceAttr(name, "auto_redirect_to_identity", "true"), + resource.TestCheckResourceAttr(name, "allowed_idps.#", "1"), + ), + }, + }, + }) +} + func testAccCloudflareAccessApplicationConfigBasic(rnd, zoneID, domain string) string { return fmt.Sprintf(` resource "cloudflare_access_application" "%[1]s" { @@ -137,6 +164,24 @@ resource "cloudflare_access_application" "%[1]s" { `, rnd, zoneID, domain) } +func testAccCloudflareAccessApplicationConfigWithADefinedIdp(rnd, zoneID, domain string, accountID string) string { + return fmt.Sprintf(` +resource "cloudflare_access_identity_provider" "%[1]s" { + account_id = "%[4]s" + name = "%[1]s" + type = "onetimepin" +} +resource "cloudflare_access_application" "%[1]s" { + zone_id = "%[2]s" + name = "%[1]s" + domain = "%[1]s.%[3]s" + session_duration = "24h" + auto_redirect_to_identity = true + allowed_idps = [cloudflare_access_identity_provider.%[1]s.id] +} +`, rnd, zoneID, domain, accountID) +} + func testAccCheckCloudflareAccessApplicationDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*cloudflare.API) diff --git a/website/docs/r/access_application.html.markdown b/website/docs/r/access_application.html.markdown index d4af7f1573..bd73e4a166 100644 --- a/website/docs/r/access_application.html.markdown +++ b/website/docs/r/access_application.html.markdown @@ -20,7 +20,7 @@ resource "cloudflare_access_application" "staging_app" { name = "staging application" domain = "staging.example.com" session_duration = "24h" - auto_redirect_to_identity = false + auto_redirect_to_identity = false } # With CORS configuration @@ -50,6 +50,8 @@ The following arguments are supported: re-authorise. Must be one of `30m`, `6h`, `12h`, `24h`, `168h`, `730h`. * `cors_headers` - (Optional) CORS configuration for the Access Application. See below for reference structure. +* `allowed_idps` - (Optional) The identity providers selected for the application. + **cors_headers** allows the following: @@ -80,6 +82,7 @@ The following additional attributes are exported: * `domain` - Domain of the application * `session_duration` - Length of session for the application before prompting for a sign in * `auto_redirect_to_identity` - If the IdP selection page is skipped or not +* `allowed_idps` - The identity providers selected for the application ## Import