Skip to content

Commit

Permalink
Merge pull request #1865 from js0cha/fix-cloudflare-worker-upload
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobbednarz authored Aug 31, 2022
2 parents f84ecd6 + 3807f16 commit 3de898e
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 177 deletions.
3 changes: 3 additions & 0 deletions .changelog/1865.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/cloudflare_worker: provide js module option to allow service bindings
```
123 changes: 82 additions & 41 deletions docs/resources/worker_script.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
---
layout: "cloudflare"
page_title: "Cloudflare: cloudflare_worker_script"
description: Provides a Cloudflare worker script resource.
page_title: "cloudflare_worker_script Resource - Cloudflare"
subcategory: ""
description: |-
Provides a Cloudflare worker script resource. In order for a script to be active, you'll also need to setup a cloudflare_worker_route.
---

# cloudflare_worker_script
# cloudflare_worker_script (Resource)

Provides a Cloudflare worker script resource. In order for a script to be active, you'll also need to setup a `cloudflare_worker_route`. _NOTE:_ This resource uses the Cloudflare account APIs. This requires setting the `CLOUDFLARE_ACCOUNT_ID` environment variable or `account_id` provider argument.
Provides a Cloudflare worker script resource. In order for a script to be active, you'll also need to setup a `cloudflare_worker_route`.

~> This resource uses the Cloudflare account APIs. This requires setting the
`CLOUDFLARE_ACCOUNT_ID` environment variable or `account_id` provider argument.

## Example Usage

```hcl
```terraform
resource "cloudflare_workers_kv_namespace" "my_namespace" {
title = "example"
}
# Sets the script with the name "script_1"
resource "cloudflare_worker_script" "my_script" {
name = "script_1"
name = "script_1"
content = file("script.js")
kv_namespace_binding {
Expand All @@ -36,69 +40,106 @@ resource "cloudflare_worker_script" "my_script" {
}
webassembly_binding {
name = "MY_EXAMPLE_WASM"
name = "MY_EXAMPLE_WASM"
module = filebase64("example.wasm")
}
service_binding {
name = "MY_SERVICE_BINDING"
service = "MY_SERVICE"
name = "MY_SERVICE_BINDING"
service = "MY_SERVICE"
environment = "production"
}
r2_bucket_binding {
name = "MY_BUCKET"
name = "MY_BUCKET"
bucket_name = "MY_BUCKET_NAME"
}
}
```

## Argument Reference
<!-- schema generated by tfplugindocs -->
## Schema

The following arguments are supported:
### Required

- `name` - (Required) The name for the script.
- `content` - (Required) The script content.
- `content` (String) The script content.
- `name` (String) The name for the script.

**kv_namespace_binding** supports:
### Optional

- `name` - (Required) The global variable for the binding in your Worker code.
- `kv_namespace_id` - (Required) ID of the KV namespace you want to use.
- `kv_namespace_binding` (Block Set) (see [below for nested schema](#nestedblock--kv_namespace_binding))
- `module` (Boolean) Whether to upload Worker as a module.
- `plain_text_binding` (Block Set) (see [below for nested schema](#nestedblock--plain_text_binding))
- `r2_bucket_binding` (Block Set) (see [below for nested schema](#nestedblock--r2_bucket_binding))
- `secret_text_binding` (Block Set) (see [below for nested schema](#nestedblock--secret_text_binding))
- `service_binding` (Block Set) (see [below for nested schema](#nestedblock--service_binding))
- `webassembly_binding` (Block Set) (see [below for nested schema](#nestedblock--webassembly_binding))

**plain_text_binding** supports:
### Read-Only

- `name` - (Required) The global variable for the binding in your Worker code.
- `text` - (Required) The plain text you want to store.
- `id` (String) The ID of this resource.

**secret_text_binding** supports:
<a id="nestedblock--kv_namespace_binding"></a>
### Nested Schema for `kv_namespace_binding`

- `name` - (Required) The global variable for the binding in your Worker code.
- `text` - (Required) The secret text you want to store.
Required:

**webassembly_binding** supports:
- `name` (String) The global variable for the binding in your Worker code.
- `namespace_id` (String) ID of the KV namespace you want to use.

- `name` - (Required) The global variable for the binding in your Worker code.
- `module` - (Required) The base64 encoded wasm module you want to store.

**service_binding** supports:
<a id="nestedblock--plain_text_binding"></a>
### Nested Schema for `plain_text_binding`

- `name` - (Required) The global variable for the binding in your Worker code.
- `service` - (Required) The name of the Worker to bind to.
- `environment` - (Optional) The name of the Worker environment to bind to.
Required:

**r2_bucket_binding** supports:
- `name` (String) The global variable for the binding in your Worker code.
- `text` (String) The plain text you want to store.

- `name` - (Required) The global variable for the binding in your Worker code.
- `bucket_name` - (Required) The name of the Bucket to bind to.

## Import
<a id="nestedblock--r2_bucket_binding"></a>
### Nested Schema for `r2_bucket_binding`

To import a script, use a script name, e.g. `script_name`
Required:

```
$ terraform import cloudflare_worker_script.default script_name
```
- `bucket_name` (String) The name of the Bucket to bind to.
- `name` (String) The global variable for the binding in your Worker code.


<a id="nestedblock--secret_text_binding"></a>
### Nested Schema for `secret_text_binding`

Required:

- `name` (String) The global variable for the binding in your Worker code.
- `text` (String, Sensitive) The secret text you want to store.


<a id="nestedblock--service_binding"></a>
### Nested Schema for `service_binding`

Required:

where:
- `name` (String) The global variable for the binding in your Worker code.
- `service` (String) The name of the Worker to bind to.

- `script_name` - the script name
Optional:

- `environment` (String) The name of the Worker environment to bind to.


<a id="nestedblock--webassembly_binding"></a>
### Nested Schema for `webassembly_binding`

Required:

- `module` (String) The base64 encoded wasm module you want to store.
- `name` (String) The global variable for the binding in your Worker code.

## Import

Import is supported using the following syntax:

```shell
$ terraform import cloudflare_worker_script.example <script_name>
```
1 change: 1 addition & 0 deletions examples/resources/cloudflare_worker_script/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$ terraform import cloudflare_worker_script.example <script_name>
40 changes: 40 additions & 0 deletions examples/resources/cloudflare_worker_script/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
resource "cloudflare_workers_kv_namespace" "my_namespace" {
title = "example"
}

# Sets the script with the name "script_1"
resource "cloudflare_worker_script" "my_script" {
name = "script_1"
content = file("script.js")

kv_namespace_binding {
name = "MY_EXAMPLE_KV_NAMESPACE"
namespace_id = cloudflare_workers_kv_namespace.my_namespace.id
}

plain_text_binding {
name = "MY_EXAMPLE_PLAIN_TEXT"
text = "foobar"
}

secret_text_binding {
name = "MY_EXAMPLE_SECRET_TEXT"
text = var.secret_foo_value
}

webassembly_binding {
name = "MY_EXAMPLE_WASM"
module = filebase64("example.wasm")
}

service_binding {
name = "MY_SERVICE_BINDING"
service = "MY_SERVICE"
environment = "production"
}

r2_bucket_binding {
name = "MY_BUCKET"
bucket_name = "MY_BUCKET_NAME"
}
}
6 changes: 6 additions & 0 deletions internal/provider/resource_cloudflare_worker_script.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io/ioutil"
"strings"

"github.com/MakeNowJust/heredoc/v2"
cloudflare "github.com/cloudflare/cloudflare-go"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
Expand All @@ -24,6 +25,9 @@ func resourceCloudflareWorkerScript() *schema.Resource {
Importer: &schema.ResourceImporter{
StateContext: resourceCloudflareWorkerScriptImport,
},
Description: heredoc.Doc(
"Provides a Cloudflare worker script resource. In order for a script to be active, you'll also need to setup a `cloudflare_worker_route`.",
),
}
}

Expand Down Expand Up @@ -137,6 +141,7 @@ func resourceCloudflareWorkerScriptCreate(ctx context.Context, d *schema.Resourc

scriptParams := cloudflare.WorkerScriptParams{
Script: scriptBody,
Module: d.Get("module").(bool),
Bindings: bindings,
}

Expand Down Expand Up @@ -285,6 +290,7 @@ func resourceCloudflareWorkerScriptUpdate(ctx context.Context, d *schema.Resourc

scriptParams := cloudflare.WorkerScriptParams{
Script: scriptBody,
Module: d.Get("module").(bool),
Bindings: bindings,
}

Expand Down
37 changes: 37 additions & 0 deletions internal/provider/resource_cloudflare_worker_script_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
const (
scriptContent1 = `addEventListener('fetch', event => {event.respondWith(new Response('test 1'))});`
scriptContent2 = `addEventListener('fetch', event => {event.respondWith(new Response('test 2'))});`
moduleContent = `export default { fetch() { return new Response('Hello world'); }, };`
encodedWasm = "AGFzbQEAAAAGgYCAgAAA" // wat source: `(module)`, so literally just an empty wasm module
)

Expand Down Expand Up @@ -61,6 +62,33 @@ func TestAccCloudflareWorkerScript_MultiScriptEnt(t *testing.T) {
})
}

func TestAccCloudflareWorkerScript_ModuleUpload(t *testing.T) {
t.Parallel()

var script cloudflare.WorkerScript
rnd := generateRandomResourceName()
name := "cloudflare_worker_script." + rnd

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccPreCheckAccount(t)
},
ProviderFactories: providerFactories,
CheckDestroy: testAccCheckCloudflareWorkerScriptDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckCloudflareWorkerScriptUploadModule(rnd),
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudflareWorkerScriptExists(name, &script, nil),
resource.TestCheckResourceAttr(name, "name", rnd),
resource.TestCheckResourceAttr(name, "content", moduleContent),
),
},
},
})
}

// Create a bucket before creating a worker script binding.
// When a cloudflare_r2_bucket resource is added, we can switch to that instead
func testAccCheckCloudflareWorkerScriptCreateBucket(t *testing.T, rnd string) {
Expand Down Expand Up @@ -141,6 +169,15 @@ resource "cloudflare_worker_script" "%[1]s" {
}`, rnd, scriptContent2, encodedWasm)
}

func testAccCheckCloudflareWorkerScriptUploadModule(rnd string) string {
return fmt.Sprintf(`
resource "cloudflare_worker_script" "%[1]s" {
name = "%[1]s"
content = "%[2]s"
module = true
}`, rnd, moduleContent)
}

func getRequestParamsFromResource(rs *terraform.ResourceState) cloudflare.WorkerRequestParams {
params := cloudflare.WorkerRequestParams{
ScriptName: rs.Primary.Attributes["name"],
Expand Down
Loading

0 comments on commit 3de898e

Please sign in to comment.