Skip to content

Commit

Permalink
Add backup_config attribute to cockroach_cluster resource
Browse files Browse the repository at this point in the history
The ability to manage backup configurations for clusters is added here.
  • Loading branch information
fantapop committed Oct 28, 2024
1 parent 4b9f275 commit 9cc0df1
Show file tree
Hide file tree
Showing 31 changed files with 830 additions and 9 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### Added

- Management of cluster backup settings is now supported using the
`backup_config` attribute on the `cockroach_cluster` resource. For more
information, refer to
[Cluster Backups](https://www.cockroachlabs.com/docs/cockroachcloud/managed-backups).

## [1.9.0] - 2024-10-07

- Added support for skipping [Innovation
Expand Down
11 changes: 11 additions & 0 deletions docs/data-sources/cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ data "cockroach_cluster" "cockroach" {
### Read-Only

- `account_id` (String) The cloud provider account ID that hosts the cluster. Needed for CMEK and other advanced features.
- `backup_config` (Attributes) (see [below for nested schema](#nestedatt--backup_config))
- `cloud_provider` (String) Cloud provider used to host the cluster. Allowed values are:
* GCP
* AWS
Expand All @@ -46,6 +47,16 @@ data "cockroach_cluster" "cockroach" {
- `state` (String) Describes whether the cluster is being created, updated, deleted, etc.
- `upgrade_status` (String) Describes the status of any in-progress CockroachDB upgrade or rollback.

<a id="nestedatt--backup_config"></a>
### Nested Schema for `backup_config`

Read-Only:

- `enabled` (Boolean) Indicates whether backups are enabled.
- `frequency_minutes` (Number) The frequency of backups in minutes.
- `retention_days` (Number) The number of days to retain backups for.


<a id="nestedatt--dedicated"></a>
### Nested Schema for `dedicated`

Expand Down
40 changes: 40 additions & 0 deletions docs/guides/updating-backup-retention.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Updating Backup Retention

Backup retention can be controlled by setting the attribute
`backup_config.retention_days` on the `cockroach_cluster` resource.

When working with backup retention, it's important to note that this value can
only be set once. It is necessary to open a support ticket to modify the
setting again. For this reason, consider the following when managing the value
in Terraform:

* (Optional) Refrain from including `backup_config.retention_days` in the `cockroach_cluster` resource to
rely on server-side management of the value instead.
* If the initial value for `backup_config.retention_days` is the default value (i.e.
30), it will be possible to modify the retention setting one more time.
* If the initial value set for `backup_config.retention_days` is not the default, it
will not be possible to modify the retention setting again. Further
modifications will require a support ticket.

Changing the value of `backup_config.retention_days` after using your one change
will be a multi-step operation. Here are two workflows that will work. Both of
these options assume you already have modified `retention_days` once and as a
result must open a support ticket:

* Change it, and then open a ticket before applying the change to Terraform. To
do this:
1. Update `backup_config.retention_days` to the new value in Terraform.
1. Before applying the run, contact support to change
`backup_config.retention_days` to the new value.
1. Apply the changes in Terraform. A Terraform `READ` operation will
complete, recognize the existing value, and update the tf state.
* Temporarily remove management of the `backup_config.retention_days` from
Terraform, update it via ticket, and then add it back. To do this:
1. Remove management of `backup_config.retention_days` from the
`cockroach_cluster` resource
1. Run the apply. Nothing will change but Terraform is no longer managing
that value.
1. Open a support ticket to update `backup_config.retention_days` to the new
value.
1. (Optional) Add `backup_config.retention_days` back to the Terraform
config with the new value and apply the no-op update.
22 changes: 22 additions & 0 deletions docs/resources/cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ resource "cockroach_cluster" "advanced" {
}
]
delete_protection = true
backup_config = {
enabled = true
frequency_minutes = 60
retention_days = 30
}
}
resource "cockroach_cluster" "standard" {
Expand All @@ -46,6 +51,11 @@ resource "cockroach_cluster" "standard" {
}
]
delete_protection = false
backup_config = {
enabled = true
frequency_minutes = 60
retention_days = 30
}
}
resource "cockroach_cluster" "basic" {
Expand Down Expand Up @@ -76,6 +86,8 @@ resource "cockroach_cluster" "basic" {

### Optional

- `backup_config` (Attributes) The backup settings for a cluster.
Each cluster has backup settings that determine if backups are enabled, how frequently they are taken, and how long they are retained for. Use this attribute to manage those settings. (see [below for nested schema](#nestedatt--backup_config))
- `cockroach_version` (String) Major version of CockroachDB running on the cluster.
- `dedicated` (Attributes) (see [below for nested schema](#nestedatt--dedicated))
- `delete_protection` (Boolean) Set to true to enable delete protection on the cluster. If unset, the server chooses the value on cluster creation, and preserves the value on cluster update.
Expand Down Expand Up @@ -111,6 +123,16 @@ Read-Only:
- `ui_dns` (String) DNS name used when connecting to the DB Console for the cluster.


<a id="nestedatt--backup_config"></a>
### Nested Schema for `backup_config`

Optional:

- `enabled` (Boolean) Indicates whether backups are enabled. If set to false, no backups will be created.
- `frequency_minutes` (Number) The frequency of backups in minutes. Valid values are [5, 10, 15, 30, 60, 240, 1440]
- `retention_days` (Number) The number of days to retain backups for. Valid values are [2, 7, 30, 90, 365]. Can only be set once, further changes require opening a support ticket. See [Updating backup retention](../guides/updating-backup-retention) for more information.


<a id="nestedatt--dedicated"></a>
### Nested Schema for `dedicated`

Expand Down
10 changes: 10 additions & 0 deletions examples/resources/cockroach_cluster/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ resource "cockroach_cluster" "advanced" {
}
]
delete_protection = true
backup_config = {
enabled = true
frequency_minutes = 60
retention_days = 30
}
}

resource "cockroach_cluster" "standard" {
Expand All @@ -31,6 +36,11 @@ resource "cockroach_cluster" "standard" {
}
]
delete_protection = false
backup_config = {
enabled = true
frequency_minutes = 60
retention_days = 30
}
}

resource "cockroach_cluster" "basic" {
Expand Down
5 changes: 5 additions & 0 deletions examples/workflows/cockroach_advanced_cluster/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ resource "cockroach_cluster" "example" {
node_count = var.cluster_node_count
}
]
backup_config = {
enabled = true
frequency_minutes = 60
retention_days = 30
}
}

data "cockroach_cluster_cert" "example" {
Expand Down
5 changes: 5 additions & 0 deletions examples/workflows/cockroach_standard_cluster/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ resource "cockroach_cluster" "example" {
upgrade_type = var.upgrade_type
}
regions = [for r in var.cloud_provider_regions : { name = r }]
backup_config = {
enabled = true
frequency_minutes = 60
retention_days = 30
}
}

resource "cockroach_sql_user" "example" {
Expand Down
2 changes: 2 additions & 0 deletions internal/provider/allowlist_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ func TestIntegrationAllowlistEntryResource(t *testing.T) {
// Create
s.EXPECT().CreateCluster(gomock.Any(), gomock.Any()).
Return(&cluster, nil, nil)
s.EXPECT().GetBackupConfiguration(gomock.Any(), clusterID).
Return(initialBackupConfig, httpOk, nil).AnyTimes()
s.EXPECT().GetCluster(gomock.Any(), clusterID).
Return(&cluster, &http.Response{Status: http.StatusText(http.StatusOK)}, nil)
s.EXPECT().AddAllowlistEntry(gomock.Any(), clusterID, &entry).Return(&entry, nil, nil)
Expand Down
2 changes: 2 additions & 0 deletions internal/provider/client_ca_cert_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ func TestIntegrationClientCACertResource(t *testing.T) {
Return(cluster, nil, nil) // CLUSTER Create()
s.EXPECT().GetCluster(gomock.Any(), clusterId).
Return(cluster, httpOkResponse, nil) // CLUSTER Create()/waitReady()
s.EXPECT().GetBackupConfiguration(gomock.Any(), clusterId).
Return(initialBackupConfig, httpOk, nil).AnyTimes()

s.EXPECT().GetCluster(gomock.Any(), clusterId).
Return(cluster, httpOkResponse, nil) // CERT Create(): dedicated check
Expand Down
2 changes: 2 additions & 0 deletions internal/provider/cluster_cert_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ func TestIntegrationClusterCertDataSource(t *testing.T) {
Return(cluster, nil, nil)
s.EXPECT().GetCluster(gomock.Any(), clusterId).
Return(cluster, httpOkResponse, nil).Times(5)
s.EXPECT().GetBackupConfiguration(gomock.Any(), clusterId).
Return(initialBackupConfig, httpOk, nil).AnyTimes()
s.EXPECT().DeleteCluster(gomock.Any(), clusterId)

testClusterCertDataSource(t, clusterName, true)
Expand Down
30 changes: 29 additions & 1 deletion internal/provider/cluster_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,23 @@ func (d *clusterDataSource) Schema(
Computed: true,
Description: "Set to true to enable delete protection on the cluster.",
},
"backup_config": schema.SingleNestedAttribute{
Computed: true,
Attributes: map[string]schema.Attribute{
"enabled": schema.BoolAttribute{
Computed: true,
Description: "Indicates whether backups are enabled.",
},
"retention_days": schema.Int64Attribute{
Computed: true,
MarkdownDescription: "The number of days to retain backups for.",
},
"frequency_minutes": schema.Int64Attribute{
Computed: true,
Description: "The frequency of backups in minutes.",
},
},
},
},
}
}
Expand Down Expand Up @@ -250,10 +267,21 @@ func (d *clusterDataSource) Read(
return
}

traceAPICall("GetBackupConfiguration")
remoteBackupConfig, _, err := d.provider.service.GetBackupConfiguration(ctx, cockroachCluster.Id)
if err != nil {
resp.Diagnostics.AddError(
"Error getting backup configuration",
fmt.Sprintf("Could not get backup configuration: %s", formatAPIErrorMessage(err)),
)
return
}


// The concept of a plan doesn't apply to data sources.
// Using a nil plan means we won't try to re-sort the region list.
var newState CockroachCluster
loadClusterToTerraformState(cockroachCluster, &newState, nil)
loadClusterToTerraformState(cockroachCluster, remoteBackupConfig, &newState, nil)
diags = resp.State.Set(ctx, newState)
resp.Diagnostics.Append(diags...)
}
Expand Down
Loading

0 comments on commit 9cc0df1

Please sign in to comment.