Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ terraform.rc

# Local dev builds (terraform dev_overrides)
.local-bin/
/terraform-provider-cloudless
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
.PHONY: docs build test fmt vet
.PHONY: docs build test fmt vet openapi-refresh

# Path to a local vodopad checkout used to regenerate the vendored OpenAPI spec.
VODOPAD_DIR ?= ../vodopad

build:
go build ./...
Expand All @@ -14,3 +17,10 @@ docs:

fmt:
go fmt ./...

# Regenerate the vendored public OpenAPI spec from a local vodopad checkout.
# Override the path with: make openapi-refresh VODOPAD_DIR=/path/to/vodopad
openapi-refresh:
cd $(VODOPAD_DIR) && OPEN_API_OUT_DIR=docs cargo run --quiet --bin gen_openapi
cp $(VODOPAD_DIR)/docs/fluence-public.yaml internal/client/mock/testdata/fluence-public.yaml
@echo "refreshed internal/client/mock/testdata/fluence-public.yaml from $(VODOPAD_DIR)"
4 changes: 2 additions & 2 deletions docs/resources/security_group_attachment.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
page_title: "cloudless_security_group_attachment Resource - cloudless"
description: |-
Bind a security group to a network interface (one SG per interface). VM ID is resolved at create-time and stored in state.
Bind a security group to a network interface (one SG per interface). VM ID is resolved at create-time and stored in state. Binding flags the VM restart_required; add a cloudless_vm_restart (depends_on this resource) to apply the rules with a single restart after all attachments.
---

# cloudless_security_group_attachment (Resource)

Bind a security group to a network interface (one SG per interface). VM ID is resolved at create-time and stored in state.
Bind a security group to a network interface (one SG per interface). VM ID is resolved at create-time and stored in state. Binding flags the VM restart_required; add a cloudless_vm_restart (depends_on this resource) to apply the rules with a single restart after all attachments.

## Example Usage

Expand Down
4 changes: 2 additions & 2 deletions docs/resources/vm_public_ip_attachment.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
page_title: "cloudless_vm_public_ip_attachment Resource - cloudless"
description: |-
Attach a cloudless_public_ip to a cloudless_vm. Both attributes are ForceNew.
Attach a cloudless_public_ip to a cloudless_vm. Both attributes are ForceNew. Attaching a public IP flags the VM restart_required; add a cloudless_vm_restart (depends_on this resource) to apply the change with a single restart after all attachments.
---

# cloudless_vm_public_ip_attachment (Resource)

Attach a cloudless_public_ip to a cloudless_vm. Both attributes are ForceNew.
Attach a cloudless_public_ip to a cloudless_vm. Both attributes are ForceNew. Attaching a public IP flags the VM restart_required; add a cloudless_vm_restart (depends_on this resource) to apply the change with a single restart after all attachments.

## Example Usage

Expand Down
50 changes: 50 additions & 0 deletions docs/resources/vm_restart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
page_title: "cloudless_vm_restart Resource - cloudless"
description: |-
Restart a VM once, but only if it is flagged restart_required. Attaching a public IP (cloudless_vm_public_ip_attachment) or binding a security group (cloudless_security_group_attachment) flags the VM restart_required, and the change only takes effect after a restart. Place this resource after those attachments (via depends_on, or the triggers map) to apply all pending changes with a single restart. It is a no-op when restart_required is not set, so it never reboots a healthy VM.
---

# cloudless_vm_restart (Resource)

Restart a VM once, but only if it is flagged restart_required. Attaching a public IP (cloudless_vm_public_ip_attachment) or binding a security group (cloudless_security_group_attachment) flags the VM restart_required, and the change only takes effect after a restart. Place this resource after those attachments (via depends_on, or the triggers map) to apply all pending changes with a single restart. It is a no-op when restart_required is not set, so it never reboots a healthy VM.

## Example Usage

```terraform
# Apply pending network changes (public-IP attach, security-group bind) with a
# single restart, only if the VM is flagged restart_required. Place it after the
# attachments so it runs last and coalesces them into one reboot.
resource "cloudless_vm_restart" "main" {
vm_id = cloudless_vm.app.id

# Re-evaluate (and replace this resource) whenever an attachment changes, so a
# new attach is followed by a fresh restart_required check.
triggers = {
public_ip = cloudless_vm_public_ip_attachment.edge.id
security_group = cloudless_security_group_attachment.edge.id
}

depends_on = [
cloudless_vm_public_ip_attachment.edge,
cloudless_security_group_attachment.edge,
]
}
```

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

### Required

- `vm_id` (String) VM to restart when restart_required is set.

### Optional

- `triggers` (Map of String) Arbitrary values that force the restart to be re-evaluated when they change. Wire attachment IDs here (e.g. the public-IP attachment id) so a new attach re-checks restart_required. Changing any value forces this resource to be replaced.

### Read-Only

- `id` (String) The ID of this resource.
- `restarted` (Boolean) Whether a restart was actually issued (false when the VM was not restart_required).


18 changes: 18 additions & 0 deletions examples/resources/cloudless_vm_restart/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Apply pending network changes (public-IP attach, security-group bind) with a
# single restart, only if the VM is flagged restart_required. Place it after the
# attachments so it runs last and coalesces them into one reboot.
resource "cloudless_vm_restart" "main" {
vm_id = cloudless_vm.app.id

# Re-evaluate (and replace this resource) whenever an attachment changes, so a
# new attach is followed by a fresh restart_required check.
triggers = {
public_ip = cloudless_vm_public_ip_attachment.edge.id
security_group = cloudless_security_group_attachment.edge.id
}

depends_on = [
cloudless_vm_public_ip_attachment.edge,
cloudless_security_group_attachment.edge,
]
}
11 changes: 11 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ require (
github.com/hashicorp/terraform-plugin-go v0.31.0
github.com/hashicorp/terraform-plugin-log v0.10.0
github.com/hashicorp/terraform-plugin-testing v1.16.0
github.com/pb33f/libopenapi v0.36.6
github.com/pb33f/libopenapi-validator v0.13.7
)

require (
Expand All @@ -21,10 +23,15 @@ require (
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/basgys/goxml2json v1.1.1-0.20231018121955-e66ee54ceaad // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect
github.com/buger/jsonparser v1.1.2 // indirect
github.com/cloudflare/circl v1.6.3 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/go-openapi/jsonpointer v0.23.1 // indirect
github.com/go-openapi/swag/jsonname v0.26.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect
Expand Down Expand Up @@ -59,7 +66,10 @@ require (
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/oklog/run v1.2.0 // indirect
github.com/pb33f/jsonpath v0.8.2 // indirect
github.com/pb33f/ordered-map/v2 v2.3.1 // indirect
github.com/posener/complete v1.2.3 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
Expand All @@ -69,6 +79,7 @@ require (
github.com/yuin/goldmark-meta v1.1.0 // indirect
github.com/zclconf/go-cty v1.18.1 // indirect
go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect
go.yaml.in/yaml/v4 v4.0.0-rc.4 // indirect
golang.org/x/crypto v0.50.0 // indirect
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
golang.org/x/mod v0.35.0 // indirect
Expand Down
Loading