diff --git a/docs/resources/service_v1.md b/docs/resources/service_v1.md
index 003f67cb6..e0c30a86a 100644
--- a/docs/resources/service_v1.md
+++ b/docs/resources/service_v1.md
@@ -236,7 +236,6 @@ $ terraform import fastly_service_v1.demo xxxxxxxxxxxxxxxxxxxx@2
### Required
-- **backend** (Block Set, Min: 1) (see [below for nested schema](#nestedblock--backend))
- **domain** (Block Set, Min: 1) A set of Domain names to serve as entry points for your Service (see [below for nested schema](#nestedblock--domain))
- **name** (String) The unique name for the Service to create
@@ -244,6 +243,7 @@ $ terraform import fastly_service_v1.demo xxxxxxxxxxxxxxxxxxxx@2
- **acl** (Block Set) (see [below for nested schema](#nestedblock--acl))
- **activate** (Boolean) Conditionally prevents the Service from being activated. The apply step will continue to create a new draft version but will not activate it if this is set to `false`. Default `true`
+- **backend** (Block Set) (see [below for nested schema](#nestedblock--backend))
- **bigquerylogging** (Block Set) (see [below for nested schema](#nestedblock--bigquerylogging))
- **blobstoragelogging** (Block Set) (see [below for nested schema](#nestedblock--blobstoragelogging))
- **cache_setting** (Block Set) (see [below for nested schema](#nestedblock--cache_setting))
@@ -295,6 +295,34 @@ $ terraform import fastly_service_v1.demo xxxxxxxxxxxxxxxxxxxx@2
- **active_version** (Number) The currently active version of your Fastly Service
- **cloned_version** (Number) The latest cloned version by the provider
+
+### Nested Schema for `domain`
+
+Required:
+
+- **name** (String) The domain that this Service will respond to. It is important to note that changing this attribute will delete and recreate the resource.
+
+Optional:
+
+- **comment** (String) An optional comment about the Domain.
+
+
+
+### Nested Schema for `acl`
+
+Required:
+
+- **name** (String) A unique name to identify this ACL. It is important to note that changing this attribute will delete and recreate the ACL, and discard the current items in the ACL
+
+Optional:
+
+- **force_destroy** (Boolean) Allow the ACL to be deleted, even if it contains entries. Defaults to false.
+
+Read-Only:
+
+- **acl_id** (String) The ID of the ACL
+
+
### Nested Schema for `backend`
@@ -330,34 +358,6 @@ Optional:
- **weight** (Number) The [portion of traffic](https://docs.fastly.com/en/guides/load-balancing-configuration#how-weight-affects-load-balancing) to send to this Backend. Each Backend receives weight / total of the traffic. Default `100`
-
-### Nested Schema for `domain`
-
-Required:
-
-- **name** (String) The domain that this Service will respond to. It is important to note that changing this attribute will delete and recreate the resource.
-
-Optional:
-
-- **comment** (String) An optional comment about the Domain.
-
-
-
-### Nested Schema for `acl`
-
-Required:
-
-- **name** (String) A unique name to identify this ACL. It is important to note that changing this attribute will delete and recreate the ACL, and discard the current items in the ACL
-
-Optional:
-
-- **force_destroy** (Boolean) Allow the ACL to be deleted, even if it contains entries. Defaults to false.
-
-Read-Only:
-
-- **acl_id** (String) The ID of the ACL
-
-
### Nested Schema for `bigquerylogging`
diff --git a/fastly/block_fastly_service_v1_backend.go b/fastly/block_fastly_service_v1_backend.go
index 5f6f77de2..058f1e081 100644
--- a/fastly/block_fastly_service_v1_backend.go
+++ b/fastly/block_fastly_service_v1_backend.go
@@ -404,7 +404,12 @@ func (h *BackendServiceAttributeHandler) Register(s *schema.Resource) error {
},
}
+ required := true
+
if h.GetServiceMetadata().serviceType == ServiceTypeVCL {
+ // backend is optional in VCL service
+ required = false
+
blockAttributes["request_condition"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
@@ -415,7 +420,8 @@ func (h *BackendServiceAttributeHandler) Register(s *schema.Resource) error {
s.Schema[h.GetKey()] = &schema.Schema{
Type: schema.TypeSet,
- Required: true,
+ Required: required,
+ Optional: !required,
Elem: &schema.Resource{
Schema: blockAttributes,
},
diff --git a/fastly/resource_fastly_service_v1_test.go b/fastly/resource_fastly_service_v1_test.go
index e443ab21c..39ae6a1f3 100644
--- a/fastly/resource_fastly_service_v1_test.go
+++ b/fastly/resource_fastly_service_v1_test.go
@@ -349,6 +349,62 @@ func TestAccFastlyServiceV1_updateInvalidBackend(t *testing.T) {
})
}
+func TestAccFastlyServiceV1_createServiceWithStaticBackend(t *testing.T) {
+ var service gofastly.ServiceDetail
+ name := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
+ domain := fmt.Sprintf("fastly-test.tf-%s.com", acctest.RandString(10))
+ snippet1 := `
+ backend F_httpbin_org {
+ .always_use_host_header = true;
+ .between_bytes_timeout = 1s;
+ .connect_timeout = 1s;
+ .dynamic = true;
+ .first_byte_timeout = 1s;
+ .host = "httpbin.org";
+ .host_header = "httpbin.org";
+ .max_connections = 200;
+ .port = "443";
+ .share_key = "foo";
+ .ssl = true;
+ .ssl_cert_hostname = "httpbin.org";
+ .ssl_check_cert = always;
+ .ssl_sni_hostname = "httpbin.org";
+ .probe = {
+ .dummy = true;
+ .initial = 5;
+ .request = "HEAD / HTTP/1.1" "Host: httpbin.org" "Connection: close";
+ .threshold = 1;
+ .timeout = 2s;
+ .window = 5;
+ }
+ }
+ `
+ snippet2 := "# just a comment line"
+
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProviderFactories: testAccProviders,
+ CheckDestroy: testAccCheckServiceV1Destroy,
+ Steps: []resource.TestStep{
+ {
+ Config: testAccServiceV1Config_staticBackend(name, domain, snippet1),
+ Check: resource.ComposeTestCheckFunc(
+ testAccCheckServiceV1Exists("fastly_service_v1.foo", &service),
+ testAccCheckFastlyServiceV1Attributes_backends(&service, name, []string{}),
+ resource.TestCheckResourceAttr(
+ "fastly_service_v1.foo", "active_version", "1"),
+ resource.TestCheckResourceAttr(
+ "fastly_service_v1.foo", "backend.#", "0"),
+ ),
+ },
+ {
+ Config: testAccServiceV1Config_staticBackend(name, domain, snippet2),
+ ExpectError: regexp.MustCompile("No backends"),
+ },
+ },
+ })
+}
+
func TestAccFastlyServiceV1_basic(t *testing.T) {
var service gofastly.ServiceDetail
name := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
@@ -847,6 +903,27 @@ resource "fastly_service_v1" "foo" {
}`, name, domain, backend)
}
+func testAccServiceV1Config_staticBackend(name, domain, snippet string) string {
+ return fmt.Sprintf(`
+resource "fastly_service_v1" "foo" {
+ name = "%s"
+ force_destroy = true
+
+ domain {
+ name = "%s"
+ }
+
+ snippet {
+ content = <<-EOT
+ %s
+ EOT
+ name = "vcl_init"
+ priority = 50
+ type = "init"
+ }
+}`, name, domain, snippet)
+}
+
func testAccServiceV1Config_backendTTL(name, domain, backend string, ttl uint) string {
return fmt.Sprintf(`
resource "fastly_service_v1" "foo" {