Git Product home page Git Product logo

terraform-provider-akc's Introduction

terraform-provider-akc

This terraform provider will allow the creation the Azure App Configuration resources, be they simple values or Key Vault secret references.

Usage example

Key-Value Resource

Configure the Akc App Configuration provider

terraform {
  required_providers {
    akc = {
      source = "arkiaconsulting/akc"
    }
  }
}

provider "akc" {
}

Create an App Configuration key-value

resource "akc_key_value" "test" {
  endpoint = azurerm_app_configuration.test.endpoint
  key      = "Key"
  value    = "my config value"
}

Create an App Configuration key-value with label

resource "akc_key_value" "config_value" {
  endpoint = azurerm_app_configuration.test.endpoint
  label    = "Dev"
  key      = "Key"
  value    = "my config value"
}

Create an App Configuration key-value with Key Vault secret reference

resource "akc_key_secret" "config_secret" {
  endpoint  = azurerm_app_configuration.test.endpoint
  label     = "Dev"
  key       = "storage-connection-string"
  secret_id = azurerm_key_vault_secret.secret.id
  latest_version = true # Trim or not the version information (default to false)
}

Key-Value data source

Source an existing key-value

data "akc_key_value" "my_value" {
  endpoint  = azurerm_app_configuration.test.endpoint
  label     = "Dev"
  key       = "Key"
}

Reference the resulting value using data.akc_key_value.my_value.value

Source an existing key-secret

data "akc_key_secret" "my_secret_id" {
  endpoint  = azurerm_app_configuration.test.endpoint
  label     = "Dev"
  key       = "Key"
}

Reference the resulting secret Id using data.akc_key_value.my_secret_id.secret_id

Feature resource

The provider has App Configuration Features support

resource "akc_feature" "dark_mode" {
  endpoint  = azurerm_app_configuration.test.endpoint
  label     = "Dev"                       # Optional
  name       = "DarkMode"
  enabled = true                          # Optional
  description = "Switch UI to dark mode"  # Optional
}

Feature data source

data "akc_feature" "dark_mode" {
  endpoint  = azurerm_app_configuration.test.endpoint
  label     = "Dev"                       # Optional
  name       = "DarkMode"
}

Authorization

The provider uses the current Azure CLI credentials if available, and fall back to environment variables.

The identity must have be assigned the RBAC role App Configuration Data Owner, or at least App Configuration Data Reader in order to use the data source.

If you don't want to connect using Azure CLI credentials, you must configure the following environment variables (terraform-azurerm standard):

export ARM_CLIENT_ID=XXXXXXXX-XXX
export ARM_SUBSCRIPTION_ID=XXXXXXXX-XXX
export ARM_TENANT_ID=XXXXXXXX-XXX
export ARM_CLIENT_SECRET=XXXXXXX
export ARM_USE_MSI=True # Optional

Installation

The provider is available on the terraform registry

terraform-provider-akc's People

Contributors

adamcoulteroz avatar arkiaconsulting avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

terraform-provider-akc's Issues

Provide documentation about possible fields for each resource in the provider

What problem are you facing

The repository has good readme examples, but I think it would be perfect if we could search for a more detailed explanation about each resource, where we could find all possible fields for each resource.

You can see an example of this type of documentation in the GCP provider, see google_sql_database resource documentation.

The repository already has "Example usage" section, but I feel that it is missing Arguments and Attributes reference.

How can terraform-provider-akc solve this problem

Creating a documentation with 3 main sections -- Example usage (already done), Arguments reference (all possible arguments, required/not required) and Attributes reference

Getting provider plugin crash

Stack trace from the terraform-provider-akc_1.1.1.exe plugin:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x40 pc=0x10720b7]

goroutine 44 [running]:
github.com/Azure/go-autorest/autorest/adal.(*ServicePrincipalToken).refreshInternal(0xc000393500, 0x1a890a0, 0xc00004e098, 0xc0004a5480, 0x1b, 0x0, 0x0)
        github.com/Azure/go-autorest/autorest/[email protected]/token.go:913 +0x717
github.com/Azure/go-autorest/autorest/adal.(*ServicePrincipalToken).EnsureFreshWithContext(0xc000393500, 0x1a890a0, 0xc00004e098, 0x0, 0x0)
        github.com/Azure/go-autorest/autorest/[email protected]/token.go:779 +0x1b4
github.com/Azure/go-autorest/autorest.(*BearerAuthorizer).WithAuthorization.func1.1(0xc0000f1600, 0xc000178480, 0x1c44371aec8, 0xf8)
        github.com/Azure/go-autorest/[email protected]/authorization.go:122 +0x112
github.com/Azure/go-autorest/autorest.PreparerFunc.Prepare(0xc000480e20, 0xc0000f1600, 0x0, 0xc00048a000, 0x0)
        github.com/Azure/go-autorest/[email protected]/preparer.go:76 +0x37
github.com/Azure/go-autorest/autorest.WithMethod.func1.1(0xc0000f1600, 0x18b8f40, 0x1, 0xc0000f1600)
        github.com/Azure/go-autorest/[email protected]/preparer.go:203 +0x58
github.com/Azure/go-autorest/autorest.PreparerFunc.Prepare(0xc00017c3c0, 0xc0000f1600, 0x3, 0xc0004a5540, 0x1a)
        github.com/Azure/go-autorest/[email protected]/preparer.go:76 +0x37
github.com/arkiaconsulting/terraform-provider-akc/client.(*Client).send(0xc0004b0d68, 0x18ccd65, 0x3, 0xc0004a5540, 0x1a, 0xc000157b38, 0x1, 0x1, 0xb9dbadfc36ff669d, 0x8, ...)
        github.com/arkiaconsulting/terraform-provider-akc/client/client.go:241 +0xf1
github.com/arkiaconsulting/terraform-provider-akc/client.(*Client).GetKeyValue(0xc0004b0d68, 0x18ccd65, 0x3, 0xc00049b3c8, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        github.com/arkiaconsulting/terraform-provider-akc/client/client.go:96 +0x153
github.com/arkiaconsulting/terraform-provider-akc/akc.dataSourceKeyValueRead.func1(0x2)
        github.com/arkiaconsulting/terraform-provider-akc/akc/data_source_key_value.go:55 +0xd8
github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource.RetryContext.func1(0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
        github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/resource/wait.go:27 +0x62
github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource.(*StateChangeConf).WaitForStateContext.func1(0xc000136600, 0xc00014a3f0, 0xc0000153e0, 0xc000176380, 0xc000493870, 0xc000493868)
        github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/resource/state.go:110 +0x309
created by github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource.(*StateChangeConf).WaitForStateContext
        github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/resource/state.go:83 +0x1d9

Error: The terraform-provider-akc_1.1.1.exe plugin crashed!

This is always indicative of a bug within the plugin. It would be immensely
helpful if you could report the crash with the plugin's maintainers so that it
can be fixed. The output above should help diagnose the issue.

Terraform Cloud

Is there different configuration required when using this module with Terraform Cloud?

`
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
}
akc = {
source = "arkiaconsulting/akc"
}
}
}

provider "azurerm"{
subscription_id = var.subscription_id
client_id = var.client_id
client_secret = var.clientsecret
tenant_id = var.tenant_id
features {}
}

provider "akc" {
}

resource "azurerm_app_configuration" "appconf" {
name = var.configStoreName
resource_group_name = azurerm_resource_group.AppConfigResourceGroup.name
location = azurerm_resource_group.AppConfigResourceGroup.location
depends_on = [azurerm_resource_group.AppConfigResourceGroup]
}

resource "akc_key_value" "config_values" {
endpoint = azurerm_app_configuration.appconf.endpoint
label = var.Label
key = var.Key
value = var.Value
depends_on = [azurerm_app_configuration.appconf,]
}
`

│ Error: Unexpected error (): azure.BearerAuthorizer#WithAuthorization: Failed to refresh the Token for request to https://###################.azconfig.io/kv/ConnectionStrings:KeyVault?api-version=1.0&label=##########: StatusCode=0 -- Original Error: adal: Failed to execute the refresh request. Error = 'Get "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2F#############.azconfig.io": dial tcp 169.254.169.254:80: i/o timeout'

EDIT: I had an error in my environment vars.

Fatal Crash: Concurrent Map Writes (v1.0.0)

This line is causing a fatal crash:

clientsCache[endpoint] = cl

@arkiaconsulting, can we please revert to letting terraform handle the lifetime of the client objects?

Stack trace from the terraform-provider-akc_1.0.0 plugin:

fatal error: concurrent map writes
fatal error: concurrent map writes

goroutine 72 [running]:
runtime.throw(0x18b5f6a, 0x15)
        runtime/panic.go:1117 +0x72 fp=0xc0006f9608 sp=0xc0006f95d8 pc=0x1035d52
runtime.mapassign_faststr(0x17c6c00, 0xc00019b9b0, 0xc0006ca860, 0x1b, 0x0)
        runtime/map_faststr.go:291 +0x3d8 fp=0xc0006f9670 sp=0xc0006f9608 pc=0x10142d8
github.com/arkiaconsulting/terraform-provider-akc/akc.getOrReuseClient(0xc0006ca860, 0x1b, 0xc0006b2900, 0x1794b00, 0xc0006e48e0, 0x1)
        github.com/arkiaconsulting/terraform-provider-akc/akc/helpers.go:22 +0xd2 fp=0xc0006f96b0 sp=0xc0006f9670 pc=0x151bef2
github.com/arkiaconsulting/terraform-provider-akc/akc.dataSourceKeyValueRead(0xc000199500, 0x17b29e0, 0xc0006b2900, 0x1e16ac0, 0xc00007c480)
        github.com/arkiaconsulting/terraform-provider-akc/akc/data_source_key_value.go:44 +0x245 fp=0xc0006f98e8 sp=0xc0006f96b0 pc=0x151b565
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).read(0xc0001a2700, 0x19a3218, 0xc0006b2d80, 0xc000199500, 0x17b29e0, 0xc0006b2900, 0x0, 0x0, 0x0)
        github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/resource.go:335 +0x1ee fp=0xc0006f9958 sp=0xc0006f98e8 pc=0x14f754e
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).ReadDataApply(0xc0001a2700, 0x19a3218, 0xc0006b2d80, 0xc0004bcc40, 0x17b29e0, 0xc0006b2900, 0xc0006b2900, 0xc0004bcc40, 0x0, 0x0)
        github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/resource.go:558 +0xfd fp=0xc0006f99e0 sp=0xc0006f9958 pc=0x14f919d
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ReadDataSource(0xc00000d560, 0x19a3218, 0xc0006b2d80, 0xc0004bcb60, 0xc0006b2d80, 0x100b665, 0x1844d60)
        github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/schema/grpc_provider.go:1105 +0x4d6 fp=0xc0006f9ae0 sp=0xc0006f99e0 pc=0x14f0d76
github.com/hashicorp/terraform-plugin-go/tfprotov5/server.(*server).ReadDataSource(0xc00061fd00, 0x19a32c0, 0xc0006b2d80, 0xc0006b58b0, 0xc00061fd00, 0xc0006dcb40, 0xc00065bba0)
        github.com/hashicorp/[email protected]/tfprotov5/server/server.go:247 +0xe5 fp=0xc0006f9b40 sp=0xc0006f9ae0 pc=0x17143c5
github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_ReadDataSource_Handler(0x18739e0, 0xc00061fd00, 0x19a32c0, 0xc0006dcb40, 0xc000055800, 0x0, 0x19a32c0, 0xc0006dcb40, 0xc0001f60e0, 0x61)
        github.com/hashicorp/[email protected]/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:416 +0x214 fp=0xc0006f9bb0 sp=0xc0006f9b40 pc=0x170c4d4
google.golang.org/grpc.(*Server).processUnaryRPC(0xc0002356c0, 0x19aa978, 0xc000316f00, 0xc0006bc300, 0xc0003026c0, 0x1dd9e30, 0x0, 0x0, 0x0)
        google.golang.org/[email protected]/server.go:1194 +0x52b fp=0xc0006f9e50 sp=0xc0006f9bb0 pc=0x16b6dcb
google.golang.org/grpc.(*Server).handleStream(0xc0002356c0, 0x19aa978, 0xc000316f00, 0xc0006bc300, 0x0)
        google.golang.org/[email protected]/server.go:1517 +0xd0c fp=0xc0006f9f68 sp=0xc0006f9e50 pc=0x16baf8c
google.golang.org/grpc.(*Server).serveStreams.func1.2(0xc000114170, 0xc0002356c0, 0x19aa978, 0xc000316f00, 0xc0006bc300)
        google.golang.org/[email protected]/server.go:859 +0xab fp=0xc0006f9fb8 sp=0xc0006f9f68 pc=0x16c8f4b
runtime.goexit()
        runtime/asm_amd64.s:1371 +0x1 fp=0xc0006f9fc0 sp=0xc0006f9fb8 pc=0x106c001
created by google.golang.org/grpc.(*Server).serveStreams.func1
        google.golang.org/[email protected]/server.go:857 +0x1fd

goroutine 1 [select]:
github.com/hashicorp/go-plugin.Serve(0xc00033be90)
        github.com/hashicorp/[email protected]/server.go:469 +0x954
github.com/hashicorp/terraform-plugin-sdk/v2/plugin.Serve(0xc0001dab40)
        github.com/hashicorp/terraform-plugin-sdk/[email protected]/plugin/serve.go:122 +0xf4
main.main()
        github.com/arkiaconsulting/terraform-provider-akc/main.go:10 +0x45

goroutine 12 [select]:
github.com/hashicorp/go-plugin.(*gRPCBrokerServer).Recv(0xc000302450, 0x0, 0x0, 0x0)
        github.com/hashicorp/[email protected]/grpc_broker.go:121 +0x86
github.com/hashicorp/go-plugin.(*GRPCBroker).Run(0xc0000980a0)
        github.com/hashicorp/[email protected]/grpc_broker.go:411 +0x7a
created by github.com/hashicorp/go-plugin.(*GRPCServer).Init
        github.com/hashicorp/[email protected]/grpc_server.go:85 +0x39c

goroutine 13 [IO wait]:
internal/poll.runtime_pollWait(0x6f53a58, 0x72, 0xffffffffffffffff)
        runtime/netpoll.go:222 +0x55
internal/poll.(*pollDesc).wait(0xc00010c138, 0x72, 0x1001, 0x1000, 0xffffffffffffffff)
        internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
        internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc00010c120, 0xc0002fb000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
        internal/poll/fd_unix.go:166 +0x1d5
os.(*File).read(...)
        os/file_posix.go:31
os.(*File).Read(0xc000306020, 0xc0002fb000, 0x1000, 0x1000, 0x400, 0x1796e60, 0x1)
        os/file.go:117 +0x77
bufio.(*Reader).Read(0xc000126f50, 0xc0000d6400, 0x400, 0x400, 0x0, 0x0, 0x0)
        bufio/bufio.go:227 +0x222
github.com/hashicorp/go-plugin.copyChan(0x19ae988, 0xc000212230, 0xc000050a20, 0x1994d20, 0xc000306020)
        github.com/hashicorp/[email protected]/grpc_stdio.go:181 +0xc5
created by github.com/hashicorp/go-plugin.newGRPCStdioServer
        github.com/hashicorp/[email protected]/grpc_stdio.go:37 +0xb1

goroutine 14 [IO wait]:
internal/poll.runtime_pollWait(0x6f53888, 0x72, 0xffffffffffffffff)
        runtime/netpoll.go:222 +0x55
internal/poll.(*pollDesc).wait(0xc00010c1f8, 0x72, 0x1001, 0x1000, 0xffffffffffffffff)
        internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
        internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc00010c1e0, 0xc00058c000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
        internal/poll/fd_unix.go:166 +0x1d5
os.(*File).read(...)
        os/file_posix.go:31
os.(*File).Read(0xc000306040, 0xc00058c000, 0x1000, 0x1000, 0x400, 0x1796e60, 0x1)
        os/file.go:117 +0x77
bufio.(*Reader).Read(0xc000127750, 0xc0000d6800, 0x400, 0x400, 0x0, 0x0, 0x0)
        bufio/bufio.go:227 +0x222
github.com/hashicorp/go-plugin.copyChan(0x19ae988, 0xc000212230, 0xc000050a80, 0x1994d20, 0xc000306040)
        github.com/hashicorp/[email protected]/grpc_stdio.go:181 +0xc5
created by github.com/hashicorp/go-plugin.newGRPCStdioServer
        github.com/hashicorp/[email protected]/grpc_stdio.go:38 +0xfe

goroutine 21 [syscall]:
os/signal.signal_recv(0x0)
        runtime/sigqueue.go:165 +0x9d
os/signal.loop()
        os/signal/signal_unix.go:23 +0x25
created by os/signal.Notify.func1.1
        os/signal/signal.go:151 +0x45

goroutine 22 [chan receive]:
github.com/hashicorp/go-plugin.Serve.func3(0xc00010c300, 0x19ae988, 0xc000212230)
        github.com/hashicorp/[email protected]/server.go:434 +0x89

Error: The terraform-provider-akc_1.0.0 plugin crashed!

aks Error when run terraform plan

I have a lot key-value pairs >100
From time to time I get en error
│ Error: error building client for endpoint https://xxxx.azconfig.io: Invoking Azure CLI failed with the following error: ERROR: The command failed with an unexpected error. Here is the traceback:
│ ERROR: Ran out of input
│ Traceback (most recent call last):
│ File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\knack/cli.py", line 231, in invoke
│ File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/init.py", line 658, in execute
│ File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/init.py", line 721, in _run_jobs_serially
│ File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/init.py", line 692, in _run_job
│ File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/init.py", line 328, in call
│ File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/command_operation.py", line 121, in handler
│ File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/command_modules/profile/custom.py", line 76, in get_access_token
│ File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/_profile.py", line 383, in get_raw_token
│ File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/_profile.py", line 593, in _create_credential
│ File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/auth/identity.py", line 209, in get_user_credential
│ File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/auth/identity.py", line 84, in _msal_app_kwargs
│ File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/auth/identity.py", line 113, in _load_msal_http_cache
│ EOFError: Ran out of input
│ To open an issue, please run: 'az feedback'

│ with akc_key_value.key-value-string[49],
│ on appconfig_config_keys.tf line 3, in resource "akc_key_value" "key-value-string":
│ 3: resource "akc_key_value" "key-value-string" {

Provider marks resources as deleted when it has no access the service

When running the plan stage on the VM with user assigned identity (where AKC provider does not work properly, see #32),
provider marks its resources as "removed" and removes them from the state.

Expected behavior - provider should report that it has no access to previously created resources.

Windows support?

Is there a reason there's no Windows build? I'd be happy to provide a GitHub action that could handle this

Cannot make the data source working

Terraform v0.14.6

  • provider registry.terraform.io/arkiaconsulting/akc v0.2.1
  • provider registry.terraform.io/hashicorp/azurerm v2.47.0

The data key vaule source does not work :(
When you run terraform plan, the following error is produced.

Error: Error getting App Configuration key %00/test: Unexpected error (Forbidden)

Single terraform file project.

terraform {
  required_providers {
    azurerm = {
        source = "hashicorp/azurerm"
        version = ">= 2.26"
    }
    akc = {
      source = "arkiaconsulting/akc"
    }
  }
}
provider "azurerm" {
    skip_provider_registration = true
    features {}
}
data "azurerm_app_configuration" "appconf" {
  name                = "app-dev-ac"
  resource_group_name = "devops-dev-rg"
}

data "akc_key_value" "application_id" {
  endpoint = data.azurerm_app_configuration.appconf.endpoint
  key      = "test"
}

Does not work with User Assigned Managed Identity

When running on Azure VM with user assigned managed identity, the provider cannot read/set/delete App Config Keys.

Terraform v1.0.4
on linux_amd64

  • provider registry.terraform.io/arkiaconsulting/akc v1.1.1
  • provider registry.terraform.io/hashicorp/azurerm v2.71.0

The error is Error: Unexpected error (Forbidden)

When creating/reading App Configuration keys with Azure cli, it works as expected

For terraform credentials are provided through [https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/managed_service_identity#configuring-with-environment-variables] (environment variables)

For Azure cli az login is used:

az login --identity -u $ARM_CLIENT_ID
az appconfig kv set --endpoint https://$ENDPOINT.azconfig.io --key color --value red --auth-mode login

data source

Do you plan to add Data Sources as well ?

Something like

data "azurerm_app_configuration" "test" {
  name                = "existing"
  resource_group_name = "existing"
}

data "akc_key_value" "config_value" {
  endpoint = azurerm_app_configuration.test.endpoint
  key      = "Key"
}

output "my_output_value" {
  value = data.akc_key_value.config_value.value
}

Using a Service Principal instead of AZ CLI. Creating a value is never ending

I still have a lot of issues, regarding the rights, when using a service principal
The value is indefinitely in the state of creating.

Here is my main.tf file

terraform {
  required_providers {
    akc = {
      source = "arkiaconsulting/akc"
    }
  }
}

provider "azurerm" {
  version = "=2.27.0"
  features {}
}


provider "null" {
  version = "~> 2.1"
}

provider "akc" {
}

# ---------------------------------------------------------

variable rg_prefix {
  default     = "rg-app-conf6"
}
variable rg_location {
  default     = "northeurope"
}
variable environment {
  default     = "dev"
}

# ---------------------------------------------------------
resource "random_string" "unique" {
  length  = 4
  special = false
  upper   = false
  number  = false
}

resource "azurerm_resource_group" "rg" {
  name     = "${var.rg_prefix}-${var.environment}"
  location = var.rg_location
  tags = {
    environment = var.environment
  }

  lifecycle {
    ignore_changes = [
      tags
    ]
  }
}

resource "azurerm_app_configuration" "app_conf"{
  name                = "conf${var.environment}${random_string.unique.result}"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  sku                 = "standard"

  lifecycle {
    ignore_changes = [
      tags
    ]
  }
}

# Waiting for the assignment propagation
resource "null_resource" "delay" {
  provisioner "local-exec" {
    command = "sleep 60"
  }

  depends_on = [
    azurerm_app_configuration.app_conf
  ]
}

resource "akc_key_value" "rg_name" {
  endpoint = azurerm_app_configuration.app_conf.endpoint
  key      = "rg_name"
  value    = azurerm_resource_group.rg.name

  depends_on = [
    null_resource.delay
  ]

}

Here is my bash commands:

# Checking the SPN Role assignments before logout 
az role assignment list --assignee 88ef9e7c-XXX -o table

#Summary of the output 
 - App Configuration Data Owner  
 - Owner                         
 - Contributor

# Be sure I'm logout
az logout

# Exporting values as mentioned here : https://www.terraform.io/docs/providers/azurerm/guides/service_principal_client_secret.html#configuring-the-service-principal-in-terraform

export ARM_CLIENT_ID=88ef9e7c-XXX
export ARM_SUBSCRIPTION_ID=6d854ccd-XXX
export ARM_TENANT_ID=72f988bf-XXX
export ARM_CLIENT_SECRET=W-tbXXX

# applying terraform script
terraform apply 

random_string.unique: Creating...
random_string.unique: Creation complete after 0s [id=fimx]
azurerm_resource_group.rg: Creating...
azurerm_resource_group.rg: Creation complete after 2s 
azurerm_app_configuration.app_conf: Creating...
azurerm_app_configuration.app_conf: Still creating... [10s elapsed]
azurerm_app_configuration.app_conf: Creation complete after 14s 
null_resource.delay: Creating...
null_resource.delay: Provisioning with 'local-exec'...
null_resource.delay (local-exec): Executing: ["/bin/sh" "-c" "sleep 60"]
null_resource.delay: Still creating... [10s elapsed]
null_resource.delay: Still creating... [20s elapsed]
null_resource.delay: Still creating... [30s elapsed]
null_resource.delay: Still creating... [40s elapsed]
null_resource.delay: Still creating... [50s elapsed]
null_resource.delay: Still creating... [1m0s elapsed]
null_resource.delay: Creation complete after 1m0s [id=4717629224581084020]
akc_key_value.rg_name: Creating...
akc_key_value.rg_name: Still creating... [10s elapsed]
akc_key_value.rg_name: Still creating... [20s elapsed]
akc_key_value.rg_name: Still creating... [30s elapsed]
akc_key_value.rg_name: Still creating... [40s elapsed]
akc_key_value.rg_name: Still creating... [50s elapsed]
akc_key_value.rg_name: Still creating... [1m0s elapsed]
akc_key_value.rg_name: Still creating... [1m10s elapsed]
akc_key_value.rg_name: Still creating... [1m20s elapsed]
akc_key_value.rg_name: Still creating... [1m30s elapsed]
akc_key_value.rg_name: Still creating... [1m40s elapsed]
akc_key_value.rg_name: Still creating... [1m50s elapsed]
akc_key_value.rg_name: Still creating... [2m0s elapsed]
akc_key_value.rg_name: Still creating... [2m10s elapsed]
akc_key_value.rg_name: Still creating... [2m20s elapsed]

Still waiting after 4 min :)

Once I interrupted the process, the error raised is:

**Error**: Unexpected error (): azure.BearerAuthorizer#WithAuthorization: Failed to refresh the Token for request to https://confdevqlzm.azconfig.io/kv/rg_name?api-version=1.0&label=%00: 
**StatusCode**=0 -- Original Error: adal: Failed to execute the refresh request. Error = 'Get "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fconfdevqlzm.azconfig.io": dial tcp 169.254.169.254:80: i/o timeout'

Creating akc_key_value Forbidden

Hello

Still have an issue when trying to create key / value entry
Here is a sample, extract from my whole project, that reproduce my issue:

terraform {
  required_providers {
    akc = {
      source = "arkiaconsulting/akc"
    }
  }
}

provider "azurerm" {
  version = "=2.27.0"
  features {}
}

provider "akc" {
}

# ---------------------------------------------------------

data "azurerm_client_config" "current" {}

# ---------------------------------------------------------

variable rg_prefix {
  default     = "rg_appconf"
}
variable rg_location {
  default     = "northeurope"
}
variable environment {
  default     = "dev"
}

# ---------------------------------------------------------
resource "random_string" "unique" {
  length  = 4
  special = false
  upper   = false
  number  = false
}

resource "azurerm_resource_group" "rg" {
  name     = "${var.rg_prefix}-${var.environment}"
  location = var.rg_location
  tags = {
    environment = var.environment
  }

  lifecycle {
    ignore_changes = [
      tags
    ]
  }
}

resource "azurerm_app_configuration" "app_conf"{
  name                = "conf${var.environment}${random_string.unique.result}"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  sku                 = "standard"

  lifecycle {
    ignore_changes = [
      tags
    ]
  }
}

# ---------------------------------------------------------

resource "azurerm_role_assignment" "app_conf_contributor_2" {
  scope                = azurerm_app_configuration.app_conf.id
  role_definition_name = "App Configuration Data Owner"
  principal_id         = data.azurerm_client_config.current.object_id
}

# ---------------------------------------------------------

resource "akc_key_value" "rg_name" {
  endpoint = azurerm_app_configuration.app_conf.endpoint
  key      = "rg_name"
  value    = azurerm_resource_group.rg.name
}

Unfortunately, the error raised is not really verbose:

akc_key_value.rg_name: Creating...

Error: Unexpected error (Forbidden)

  on main.tf line 60, in resource "akc_key_value" "rg_name":
  60: resource "akc_key_value" "rg_name" {

Obviously, I'm the owner of the subscription, and i'm able to create an entry from the azure portal.

Error: Provider produced inconsistent result after apply

I saw that this was referenced in #6 but I thought I would reopen and provide a bit more color. We are using this as a way to setup ephemeral environments (effectively each branch gets its new environment) and we are getting this error rather regularly, and I think it is related to the number of variables we are now putting into our configuration environments as it was super rare, and now its rather common.

Workaround:

  • Manually delete the key, and rerun the build.

Environment:

  • AzureDevOps Pipeline

Authorization:

  • Azure CLI

YML

steps:

  - task: TerraformInstaller@0
    displayName: Install Terraform
    inputs:
      terraformVersion: '0.15.3'

  - task: AzureCLI@2
    displayName: Provision Environment
    env:
      SourceBranchName: $(BranchName)
    inputs:
      azureSubscription: 'XYZ'
      scriptType: 'bash'
      scriptLocation: 'inlineScript'
      addSpnToEnvironment: true
      useGlobalConfig: true
     inlineScript: |
          ls
          az logout
          az login --service-principal -u http://azure-cli-own-service-principal -p $(AZURE_CLIENT_SECRET) --tenant GUIDFROMAZURE

          export AZURE_CLIENT_ID=$(AZURE_CLIENT_ID)
          export AZURE_CLIENT_SECRET=$(AZURE_CLIENT_SECRET)
          export AZURE_SUBSCRIPTION_ID=$(AZURE_SUBSCRIPTION_ID)
          export AZURE_TENANT_ID=$(AZURE_TENANT_ID)

          export ARM_CLIENT_ID=$(AZURE_CLIENT_ID)
          export ARM_CLIENT_SECRET=$(AZURE_CLIENT_SECRET)
          export ARM_SUBSCRIPTION_ID=$(AZURE_SUBSCRIPTION_ID)
          export ARM_TENANT_ID=$(AZURE_TENANT_ID)

          terraform init
          terraform plan -out=tfplan -input=false
          terraform apply -auto-approve "tfplan"

Terraform::


variable "location" {
  type    = string
  default = "westus"
}

variable "prefix" {
  type    = string
  default = "cmpyname"
}

variable "branch" {
  type    = string
  default = "gitbranch"
}

variable "production_grade" {
  type = bool
  description = "If set to true, will use production SKUs for products"
  default = false
}

variable "app_keys" {
  type = map
  default = {
    "1" : "key1"
    "2" : "key2"
    "3" : "key3"
    "4" : "key4"
    "5" : "key5"
    "6" : "key6"
    "7" : "key7"
    "8" : "key8"
    "9" : "key9"
    "10" : "key10"
    "11" : "key11"
    "12" : "key12"
    "13" : "key13"
    "14" : "key14"
    "15" : "key15"
    "16" : "key16"
    "17" : "key17"
    "18" : "key18"
    "19" : "key19"
    "20" : "key20"
    "21" : "key21"
    "22" : "key22"
    "23" : "key23"
    "24" : "key24"
    "25" : "key25"
    "26" : "key26"
    "27" : "key27"
    "28" : "key28"
    "29" : "key29"
    "30" : "key30"
    "31" : "key31"
    "32" : "key32"
    "33" : "key33"
    "34" : "key34"
    "35" : "key35"
    "36" : "key36"
    "37" : "key37"
    "38" : "key38"
    "39" : "key39"
    "40" : "key40"
    "41" : "key41"
    "42" : "key42"
    "43" : "key43"
    "44" : "key44"
    "45" : "key45"
    "46" : "key46"
    "47" : "key47"
    "48" : "key48"
    "49" : "key49"
    "50" : "key50"
    "51" : "key51"
    "52" : "key52"
    "53" : "key53"
    "54" : "key54"
    "55" : "key55"
    "56" : "key56"
    "57" : "key57"
    "58" : "key58"
    "59" : "key59"
    "60" : "key60"
    "61" : "key61"
    "62" : "key62"
    "63" : "key63"
    "64" : "key64"
    "65" : "key65"
    "66" : "key66"
    "67" : "key67"
    "68" : "key68"
    "69" : "key69"
    "70" : "key70"
    "71" : "key71"
    "72" : "key72"
    "73" : "key73"
    "74" : "key74"
    "75" : "key75"
    "76" : "key76"
    "77" : "key77"
    "78" : "key78"
    "79" : "key79"
    "80" : "key80"
    "81" : "key81"
    "82" : "key82"
    "83" : "key83"
    "84" : "key84"
    "85" : "key85"
    "86" : "key86"
    "87" : "key87"
    "88" : "key88"
    "89" : "key89"
    "90" : "key90"
    "91" : "key91"
    "92" : "key92"
    "93" : "key93"
    "94" : "key94"
    "95" : "key95"
    "96" : "key96"
    "97" : "key97"
    "98" : "key98"
    "99" : "key99"
    "100" : "key100"
    "101" : "key101"
    "102" : "key102"
    "103" : "key103"
    "104" : "key104"
    "105" : "key105"
    "106" : "key106"
    "107" : "key107"
    "108" : "key108"
    "109" : "key109"
    "110" : "key110"
    "111" : "key111"
    "112" : "key112"
    "113" : "key113"
    "114" : "key114"
    "115" : "key115"
    "116" : "key116"
    "117" : "key117"
    "118" : "key118"
    "119" : "key119"
    "120" : "key120"
    "121" : "key121"
    "122" : "key122"
    "123" : "key123"
    "124" : "key124"
    "125" : "key125"
    "126" : "key126"
    "127" : "key127"
    "128" : "key128"
    "129" : "key129"
    "130" : "key130"
    "131" : "key131"
    "132" : "key132"
    "133" : "key133"
    "134" : "key134"
    "135" : "key135"
    "136" : "key136"
    "137" : "key137"
    "138" : "key138"
    "139" : "key139"
    "140" : "key140"
    "141" : "key141"
    "142" : "key142"
    "143" : "key143"
    "144" : "key144"
    "145" : "key145"
    "146" : "key146"
    "147" : "key147"
    "148" : "key148"
    "149" : "key149"
    "150" : "key150"
    "151" : "key151"
    "152" : "key152"
    "153" : "key153"
    "154" : "key154"
    "155" : "key155"
    "156" : "key156"
    "157" : "key157"
    "158" : "key158"
    "159" : "key159"
    "160" : "key160"
    "161" : "key161"
    "162" : "key162"
    "163" : "key163"
    "164" : "key164"
    "165" : "key165"
    "166" : "key166"
    "167" : "key167"
    "168" : "key168"
    "169" : "key169"
    "170" : "key170"
    "171" : "key171"
    "172" : "key172"
    "173" : "key173"
    "174" : "key174"

  }
}


resource "akc_key_value" "app_keys" {
  for_each = var.app_keys

  endpoint = azurerm_app_configuration.appconf.endpoint
  key      = "${each.key}"
  value    = "${each.value}"
  label    = var.branch

  depends_on = [
    null_resource.delay
  ]
}

# Waiting for the assignment propagation
resource "null_resource" "delay" {
  provisioner "local-exec" {
    command = "sleep 60"
  }

  depends_on = [
    azurerm_app_configuration.appconf
  ]
}

resource "azurerm_app_configuration" "appconf" {
  name                = "${var.prefix}-${var.branch}-app-config"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  tags     = var.tags
  sku      = "${var.production_grade == "true" ? "standard" : "standard"}"   # only 1 free configuration store per Azure subscription.
}                                                                            # keeping this in here to show how to use production grade flag.

resource "azurerm_role_assignment" "app_conf_contributor_2" {
  scope                = azurerm_app_configuration.appconf.id
  role_definition_name = "App Configuration Data Owner"
  principal_id         = data.azurerm_client_config.current.object_id
}

resource "azurerm_resource_group" "rg" {
  name     = "${var.prefix}-${var.branch}-rg"  # dynamically set in the build to prefix-branchsuffix-RG
  location = var.location
  tags     = var.tags
}

Unrelated - love the plugin and it should really be apart of azurerm.

Error with Applying

Error: Unexpected error (Forbidden)

on main.tf line 60, in resource "akc_key_value" "rg_name":
60: resource "akc_key_value" "rg_name" {

I can confirm that I encountered Forbidden though I am owner and contributor to the target subscription. What fixed it for me was explicitly adding myself as App Configuration Data Owner to the subscription, and waiting ~10 minutes before applying again. The documentation states App Configuration Data Owner is required, but I assumed that because I was subscription owner I wouldn't need it explicitly.

https://www.gitmemory.com/issue/arkiaconsulting/terraform-provider-akc/3/753067706

With azure cli I can add data without adding myself to App Configuration Data Owner to that resource

Identity not found, when deployed from Azure devops

I'm not done with strange behaviors :)

I've a different behavior when I'm trying to deploy from azure devops and from my machine.
To be sure I've the same rights, I'm using the same Service Principal in Devops an locally on my machine

 az account show
{
  "environmentName": "AzureCloud",
  "id": "6d854ccd-XXX",
  "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
  "user": {
    "name": "88ef9e7c-XXX",
    "type": "servicePrincipal"
  }
}

This service principal is the one used in devops as well.
Obviously this SPN has the "owner" and "app conf contributor" role assigned.

image

Locally, everything is working fine.
In my script (the same as the last closed issue) I'm waiting a bit (180 s) to be sure everything is deployed correctly, role assignement and so on... before trying to create a key / value inside my app conf.

Eventually everything runs smoothly locally:

image

But unfortunatelly from Azure Devops i've this error raised:
image

azure.BearerAuthorizer#WithAuthorization: Failed to refresh the Token for request to https://confdevjlcn.azconfig.io/kv/rg_name?api-version=1.0&label=%00: StatusCode=400 
-- Original Error: adal: Refresh request failed. Status Code = '400'. 
Response body: {"error":"invalid_request","error_description":"Identity not found"}�[0m

2020-10-06T16:27:38.3860725Z �[0m  on main.tf line 102, in resource "akc_key_value" "rg_name":
2020-10-06T16:27:38.3861695Z  102: resource "akc_key_value" "rg_name" �[4m{�[0m

i'm going crazy with this "identity not found" issue ...

unexpected value

Note sure this one will be easy to debug
Seems I've a new random failure from devops deployment:

2020-10-06T16:59:10.2073170Z �[1m�[31mError: �[0m�[0m�[1mProvider produced inconsistent result after apply�[0m
2020-10-06T16:59:10.2073627Z 
2020-10-06T16:59:10.2074499Z �[0mWhen applying changes to akc_key_value.cosmosdb_endpoint_url, provider
2020-10-06T16:59:10.2074897Z "registry.terraform.io/arkiaconsulting/akc" produced an unexpected new value:
2020-10-06T16:59:10.2075242Z Root resource was present, but now absent.
2020-10-06T16:59:10.2075765Z 
2020-10-06T16:59:10.2076263Z This is a bug in the provider, which should be reported in the provider's own
2020-10-06T16:59:10.2076509Z issue tracker.
2020-10-06T16:59:10.2076778Z �[0m�[0m

The weird thing here, is that the pipeline have created several entries before failing on this one...

Resolve a vault secret

Hello,
I'm testing your provider (thank you to have developed this) and wondering if I misunderstood something or if this is the way to go. Right now, when I try to fetch a secret in app config, I end up with the vault url. However, I don't have the information of where that vault is (ie, resource group).
This is what I came up with to get the real value in terraform but I hope there is something easier than this.

data "akc_key_secret" "my_secret" {
  endpoint = data.azurerm_app_configuration.example.endpoint
  key      = "mysecretkey"
}

data "azurerm_resources" "vault" {
  type = "Microsoft.KeyVault/vaults"
  name = regex("https://(?P<vault_name>.*).vault.azure.net/secrets/(?P<secret_name>.*)", data.akc_key_secret.my_secret.secret_id)["vault_name"]
}

data "azurerm_key_vault_secret" "example" {
  name         = regex("https://(?P<vault_name>.*).vault.azure.net/secrets/(?P<secret_name>.*)", data.akc_key_secret.my_secret.secret_id)["secret_name"]
  key_vault_id = data.azurerm_resources.vault.resources[0].id
}

output "realsecret" {
  value = data.azurerm_key_vault_secret.example.value
}

Is this the only way today ?
Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.