hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
42.31k stars 9.49k forks source link

[Feature] Support for backend state with private link #34640

Open AndreasAugustin opened 7 months ago

AndreasAugustin commented 7 months ago

Is there an existing issue for this?

Community Note

Description

Currently it seems the backend state domain is hard coded. Would be super nice to be able to configure the backend state to use a private link.

Remark It is possible to tweak the DNS to resolve the public domains to the private endpoint but there are use cases where this is not wanted/possible.

New or Affected Resource(s)/Data Source(s)

backend azurerm

Potential Terraform Configuration

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>3.0"
    }
  }
  backend "azurerm" {
      resource_group_name        = "tfstate"
      storage_account_name       = "<storage_account_name>"
      container_name             = "tfstate"
      key                        = "terraform.tfstate"
      # new:
      private_link_domain_prefix = <my_privatelink_domain_prefix>
  }

}

References

No response

rcskosir commented 7 months ago

Thanks for taking the time to open this feature request. The Azurerm backend lives in the hashicorp/terraform repo, so I am going to move this feature request there.

AndreasAugustin commented 7 months ago

Remark

Reading the code:

Possibly it is already possible to use this feature if you set the storageAccountName parameter to storageAccountName: <hosted_zone_prefix>.privatelink and a documentation addon could help.

The related part should be located within https://github.com/tombuildsstuff/giovanni/blob/v0.15.1/storage/internal/endpoints/endpoints.go

// GetBlobEndpoint returns the endpoint for Blob API Operations on this storage account
func GetBlobEndpoint(baseUri string, accountName string) string {
    return fmt.Sprintf("https://%s.blob.%s", accountName, baseUri)
}

With a fast check of the code I did not find any sanity verification steps prohibiting this behaviour. Also the unit tests are still green with adjusting the accountName (adding .privatelink) Maybe I find time tomorrow to test this.

Update Unfortunately this workaround does not work for any reason.

Devvox93 commented 7 months ago

I can confirm that this is already possible. You need to do something like this:

terraform {
  backend "azurerm" {
    use_azuread_auth = true
    resource_group_name  = "$($BackendResourceGroupName)"
    storage_account_name = "$($BackendStorageAccountName)"
    container_name       = "$($BackendContainerName)"
    key                  = "$($BackendKeyName)"
  }
}

And make sure to have your env settings set:

env:
      ARM_TENANT_ID: $(ARM_TENANT_ID)
      ARM_SUBSCRIPTION_ID: $(ARM_SUBSCRIPTION_ID)
      ARM_CLIENT_ID: $(ARM_CLIENT_ID)
      ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)

I'd say you could close this issue. Good luck! :)

AndreasAugustin commented 7 months ago

I can confirm that this is already possible. You need to do something like this:

terraform {
  backend "azurerm" {
    use_azuread_auth = true
    resource_group_name  = "$($BackendResourceGroupName)"
    storage_account_name = "$($BackendStorageAccountName)"
    container_name       = "$($BackendContainerName)"
    key                  = "$($BackendKeyName)"
  }
}

And make sure to have your env settings set:

env:
      ARM_TENANT_ID: $(ARM_TENANT_ID)
      ARM_SUBSCRIPTION_ID: $(ARM_SUBSCRIPTION_ID)
      ARM_CLIENT_ID: $(ARM_CLIENT_ID)
      ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)

I'd say you could close this issue. Good luck! :)

@devvox93 thanks a lot for testing and verifying. Can you please add some more details how you used the private link for the storage account (e.g. did you use the private link prefix as the account name )? Thanks :)

Devvox93 commented 6 months ago

@AndreasAugustin We just use the normal storage account name. I believe Azure (almost) always handles private link routing by itself, unless you have custom DNS resolution. Could that be an issue in your case?

AndreasAugustin commented 6 months ago

@AndreasAugustin We just use the normal storage account name. I believe Azure (almost) always handles private link routing by itself, unless you have custom DNS resolution. Could that be an issue in your case?

there are cases where the recursive DNS resolution from public to private link is not working (e.g. you only have on premise DNS forwarding in place for private links and not a recursive resolve enabled ). In those cases it is not possible to resolve the public FQDN to the private link one and it would be super convenient to be able to configure the backend state to use the private link instead of the storage account name (like mentioned in the description).