Azure backend: support snapshots/versioning (#24069)
* Azure backend: support snapshots/versioning Co-authored-by: Reda Ahdjoudj <reda.ahdjoudj@gmail.com> Co-authored-by: Patrick F. Marques <patrickfmarques@gmail.com> * Azure backend: Versioning -> Snapshot Co-authored-by: Reda Ahdjoudj <reda.ahdjoudj@gmail.com> Co-authored-by: Patrick F. Marques <patrickfmarques@gmail.com>
This commit is contained in:
parent
f1ea705dbe
commit
0f85b283b9
|
@ -51,6 +51,13 @@ func New() backend.Backend {
|
||||||
DefaultFunc: schema.EnvDefaultFunc("ARM_SAS_TOKEN", ""),
|
DefaultFunc: schema.EnvDefaultFunc("ARM_SAS_TOKEN", ""),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"snapshot": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Enable/Disable automatic blob snapshotting",
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("ARM_SNAPSHOT", false),
|
||||||
|
},
|
||||||
|
|
||||||
"resource_group_name": {
|
"resource_group_name": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
@ -150,6 +157,7 @@ type Backend struct {
|
||||||
containerName string
|
containerName string
|
||||||
keyName string
|
keyName string
|
||||||
accountName string
|
accountName string
|
||||||
|
snapshot bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type BackendConfig struct {
|
type BackendConfig struct {
|
||||||
|
@ -180,6 +188,7 @@ func (b *Backend) configure(ctx context.Context) error {
|
||||||
b.containerName = data.Get("container_name").(string)
|
b.containerName = data.Get("container_name").(string)
|
||||||
b.accountName = data.Get("storage_account_name").(string)
|
b.accountName = data.Get("storage_account_name").(string)
|
||||||
b.keyName = data.Get("key").(string)
|
b.keyName = data.Get("key").(string)
|
||||||
|
b.snapshot = data.Get("snapshot").(bool)
|
||||||
|
|
||||||
// support for previously deprecated fields
|
// support for previously deprecated fields
|
||||||
clientId := valueFromDeprecatedField(data, "client_id", "arm_client_id")
|
clientId := valueFromDeprecatedField(data, "client_id", "arm_client_id")
|
||||||
|
|
|
@ -90,6 +90,7 @@ func (b *Backend) StateMgr(name string) (state.State, error) {
|
||||||
containerName: b.containerName,
|
containerName: b.containerName,
|
||||||
keyName: b.path(name),
|
keyName: b.path(name),
|
||||||
accountName: b.accountName,
|
accountName: b.accountName,
|
||||||
|
snapshot: b.snapshot,
|
||||||
}
|
}
|
||||||
|
|
||||||
stateMgr := &remote.State{Client: client}
|
stateMgr := &remote.State{Client: client}
|
||||||
|
|
|
@ -21,6 +21,7 @@ func TestBackendConfig(t *testing.T) {
|
||||||
"storage_account_name": "tfaccount",
|
"storage_account_name": "tfaccount",
|
||||||
"container_name": "tfcontainer",
|
"container_name": "tfcontainer",
|
||||||
"key": "state",
|
"key": "state",
|
||||||
|
"snapshot": false,
|
||||||
// Access Key must be Base64
|
// Access Key must be Base64
|
||||||
"access_key": "QUNDRVNTX0tFWQ0K",
|
"access_key": "QUNDRVNTX0tFWQ0K",
|
||||||
}
|
}
|
||||||
|
@ -33,6 +34,9 @@ func TestBackendConfig(t *testing.T) {
|
||||||
if b.keyName != "state" {
|
if b.keyName != "state" {
|
||||||
t.Fatalf("Incorrect keyName was populated")
|
t.Fatalf("Incorrect keyName was populated")
|
||||||
}
|
}
|
||||||
|
if b.snapshot != false {
|
||||||
|
t.Fatalf("Incorrect snapshot was populated")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBackendAccessKeyBasic(t *testing.T) {
|
func TestBackendAccessKeyBasic(t *testing.T) {
|
||||||
|
|
|
@ -5,11 +5,14 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
"github.com/hashicorp/go-uuid"
|
"github.com/hashicorp/go-uuid"
|
||||||
|
"github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/blobs"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/state"
|
"github.com/hashicorp/terraform/state"
|
||||||
"github.com/hashicorp/terraform/state/remote"
|
"github.com/hashicorp/terraform/state/remote"
|
||||||
"github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/blobs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -24,6 +27,7 @@ type RemoteClient struct {
|
||||||
containerName string
|
containerName string
|
||||||
keyName string
|
keyName string
|
||||||
leaseID string
|
leaseID string
|
||||||
|
snapshot bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RemoteClient) Get() (*remote.Payload, error) {
|
func (c *RemoteClient) Get() (*remote.Payload, error) {
|
||||||
|
@ -67,6 +71,18 @@ func (c *RemoteClient) Put(data []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
|
if c.snapshot {
|
||||||
|
snapshotInput := blobs.SnapshotInput{LeaseID: options.LeaseID}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Snapshotting existing Blob %q (Container %q / Account %q)", c.keyName, c.containerName, c.accountName)
|
||||||
|
if _, err := c.giovanniBlobClient.Snapshot(ctx, c.accountName, c.containerName, c.keyName, snapshotInput); err != nil {
|
||||||
|
return fmt.Errorf("error snapshotting Blob %q (Container %q / Account %q): %+v", c.keyName, c.containerName, c.accountName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Print("[DEBUG] Created blob snapshot")
|
||||||
|
}
|
||||||
|
|
||||||
blob, err := c.giovanniBlobClient.GetProperties(ctx, c.accountName, c.containerName, c.keyName, getOptions)
|
blob, err := c.giovanniBlobClient.GetProperties(ctx, c.accountName, c.containerName, c.keyName, getOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if blob.StatusCode != 404 {
|
if blob.StatusCode != 404 {
|
||||||
|
|
|
@ -154,6 +154,8 @@ The following configuration options are supported:
|
||||||
|
|
||||||
* `environment` - (Optional) The Azure Environment which should be used. This can also be sourced from the `ARM_ENVIRONMENT` environment variable. Possible values are `public`, `china`, `german`, `stack` and `usgovernment`. Defaults to `public`.
|
* `environment` - (Optional) The Azure Environment which should be used. This can also be sourced from the `ARM_ENVIRONMENT` environment variable. Possible values are `public`, `china`, `german`, `stack` and `usgovernment`. Defaults to `public`.
|
||||||
|
|
||||||
|
* `snapshot` - (Optional) Should the Blob used to store the Terraform Statefile be snapshotted before use? Defaults to `false`. This value can also be sourced from the `ARM_SNAPSHOT` environment variable.
|
||||||
|
|
||||||
* `endpoint` - (Optional) The Custom Endpoint for Azure Resource Manager. This can also be sourced from the `ARM_ENDPOINT` environment variable.
|
* `endpoint` - (Optional) The Custom Endpoint for Azure Resource Manager. This can also be sourced from the `ARM_ENDPOINT` environment variable.
|
||||||
|
|
||||||
~> **NOTE:** An `endpoint` should only be configured when using Azure Stack.
|
~> **NOTE:** An `endpoint` should only be configured when using Azure Stack.
|
||||||
|
|
Loading…
Reference in New Issue