Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: export Functions host keys #699

Closed
gunzip opened this issue Jan 15, 2018 · 25 comments · Fixed by #7902
Closed

Feature request: export Functions host keys #699

gunzip opened this issue Jan 15, 2018 · 25 comments · Fixed by #7902

Comments

@gunzip
Copy link

gunzip commented Jan 15, 2018

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform Version

0.10.6

Affected Resource(s)

azurerm_function_app

Expected Behavior

Should export Functions host keys

Actual Behavior

It only exports id and default_hostnames:
https://www.terraform.io/docs/providers/azurerm/r/function_app.html#attributes-reference

@TsuyoshiUshio
Copy link
Contributor

Hi @tombuildsstuff , @katbyte

I also want this feature, do you plan to implement this feature?
If not, I'd love to contribute it.

@katbyte
Copy link
Collaborator

katbyte commented Jun 10, 2018

Hi @TsuyoshiUshio,

Currently this is not on our short term roadmap so if you were to contribute it would be fantastic 🙂

@TsuyoshiUshio
Copy link
Contributor

TsuyoshiUshio commented Jul 3, 2018

Hi @katbyte, @tombuildsstuff

I have a question for implementing this feature.

I finish investigating how to implement it now ready to code. However, I have one question. This API is not the API of AppService. https://github.com/Azure/azure-functions-host/wiki/Key-management-API

Also, Lifecycle is slight different from the creation of the FunctionApp. The function Key is auto generated for each Azure Functions. Which means process is something like this.

  1. Create a Function App
  2. Deploy Functions on the function app
  3. Get the AdminAccessToken from the AppService API
  4. Retrive the Function Keys (via KeyManagement API)

In this case, we can't fetch the functions key from the function_app resource. We need to create a new resource. However, we don't need to create the new resource. Usually, Terraform resource has Create/Update/Read methods. The new resource (maybe, azure_arm_function_app_keys) only requires Read. If we add something, the API can re-generate the key (I'm not sure we need this or not). In this case, how can I implement that. Just empty implementation of Create/Update with delegate to Read method is right?

@TsuyoshiUshio
Copy link
Contributor

I might understand. All I need is implement data_source_function_app.go , right? When I contributed this repo last time, you might haven't had it, right? I'll start to create pull request. :)

@lawrencegripper
Copy link
Contributor

If anyone ends up here looking for a workaround while the API's are updated in the Go SDK to enable this feature I wrote one up here: https://blog.gripdev.xyz/2019/07/16/terraform-get-azure-function-key/

@frankie567
Copy link

@lawrencegripper You saved my day, your solution works perfectly.

As a side note, when dealing with EventGrid triggers, we need the system key, not the default one (a 401 is raised in that case). So change this part:

 "value": "[listkeys(concat(variables('functionAppId'), '/host/default'), '2018-11-01').functionKeys.default]"

To this:

"value": "[listkeys(concat(variables('functionAppId'), '/host/default'), '2018-11-01').systemKeys.eventgrid_extension]"

@haodeon
Copy link

haodeon commented Jan 27, 2020

It is possible to use "az rest --method post" to call the listKeys api to retrieve the keys. Pipe that into jq '.systemKeys.eventgridextensionconfig_extension' to pull the right key.

Wrap this into a local-exec so it becomes part of the terraform config.

@Bessonov
Copy link

Bessonov commented Feb 9, 2020

Gathered from different sources would like to post our workaround:

data "external" "hostKey" {
	program = ["bash", "-c", "az rest --method post --uri ${azurerm_resource_group.storage_service.id}/providers/Microsoft.Web/sites/${azurerm_function_app.function.name}/host/default/listKeys?api-version=2018-11-01 --query systemKeys"]

	depends_on = [
		azurerm_function_app.function
	]
}

resource "azurerm_eventgrid_event_subscription" "event_subscription" {
[...]
	webhook_endpoint {
		url = "https://${azurerm_function_app.function.name}.azurewebsites.net/runtime/webhooks/eventgrid?functionName=Thumbnail&code=${data.external.hostKey.result.eventgrid_extension}"
	}

	lifecycle {
		ignore_changes = [
			webhook_endpoint,
		]
	}
}

The depends_on is important at least for linux functions (was not needed for windows functions). This isn't very portable, but much simpler than ARM-based workaround.

@markti
Copy link
Contributor

markti commented Feb 15, 2020

@Bessonov when I use that CLI command I get "{}" as the return. I suspect that's because I haven't deployed any code packages to my Azure Function and that the eventgrid extension is automatically loaded whenever a code deployment with an EventGridTrigger is loaded there...

@danstis
Copy link

danstis commented Apr 8, 2020

I would love to see host keys treated as a resource, where we could import an existing key into the Terraform state, but also have the ability to create new custom host keys so we can align keys for geo-redundant resources.
In my mind @TsuyoshiUshio it would be good to have the ability to Read/Create/Update/Delete.

@eltimmo
Copy link
Contributor

eltimmo commented May 21, 2020

It'd be great to see this implemented, this is causing problems all over the place now. I used the ARM template method to get the keys, and this worked fine until recently. However this now fails due to timing reasons, I'm not sure if anyone else is seeing this?.

The template is called after the function creates, using the functions ID as the dependency. By the time I re-run the template or deployment this always works. I will look at options with a retry or some other logic as a work around.

@eltimmo
Copy link
Contributor

eltimmo commented May 21, 2020

@Bessonov when I use that CLI command I get "{}" as the return. I suspect that's because I haven't deployed any code packages to my Azure Function and that the eventgrid extension is automatically loaded whenever a code deployment with an EventGridTrigger is loaded there...

Hi, I had the same issue with this extension. To automate this I had our developers create a deployable package with the extension as a .zip. Then I created a function in terraform that deployed this and then extracted the key using and ARM template. There's a good example of how to deploy a packaged function here Deploying an Azure Function App with Terraform

@markti
Copy link
Contributor

markti commented May 22, 2020

@eltimmo this happens to me somtimes, what I have found is that if the RGT resource that is pulling the function key fails to provision in terraform its because there is a failed deployment in the resource group history. If I delete that failed deployment and try terraform again it works! Check out my updated module library for azure functions:

https://github.com/markti/tf_azure_fn

this one demonstrates how to use the tf_azure_fn modules....

https://github.com/markti/tf_azure_microservices

I use the same technique for the eventgrid key...but the host key I can get without deploying any code...I think the problem with EventGrid key is that the EventGrid extension is only loaded (which generates the event grid key) when Azure Functions detects that the DLL contains a class decorated with [EventGridTrigger]

@ttjackott

This comment has been minimized.

@eltimmo
Copy link
Contributor

eltimmo commented Jun 3, 2020

Hi, I've created a TF module that waits and gets a key of your choice. It uses a combination of methods described in this thread to do this. It uses powershell 7 to get the key, so it's able to keep trying until it's available. I've been using this for a couple of weeks and it's reliable. I've not tested in Linux, also I've not tested it yet with the function extenion keys but it should work.

Azure Function: get-keys

@prabhakarreddy1234

This comment has been minimized.

@georghildebrand

This comment has been minimized.

@3mard
Copy link

3mard commented Jul 26, 2020

Good news guys, ListHostKeys is part of the go-sdk now, I opened a PR to resolve this issue
#7902

@prabhakarreddy1234
Copy link

In which AzureRM release we can expect this feature?

@lawrencegripper
Copy link
Contributor

lawrencegripper commented Aug 1, 2020

Does it successfully return the key? In my attempts a while back the call existed in the SDK but always returned an empty value due to an issue with the services spec.

See #4066

@3mard
Copy link

3mard commented Aug 1, 2020

@lawrencegripper Looks like they have fixed it, as I was able to successfully fetch the keys (check the test in the PR )

@marcin-dudek
Copy link
Contributor

marcin-dudek commented Aug 13, 2020

@lawrencegripper thanks for the blog post, it helps a lot.

Currently using workaround desribed in https://blog.gripdev.xyz/2019/07/16/terraform-get-azure-function-key/. However noticed that when deploying infratructure for the first time it fails. With below error.

In order to get successful consecutive deployments, I need to delete failed deployment and deploy function app. Does anyone know fix for this one?

{ "Code": "BadRequest", "Message": "Encountered an error (ServiceUnavailable) from host runtime.", "Target": null, "Details": [ { "Message": "Encountered an error (ServiceUnavailable) from host runtime." }, { "Code": "BadRequest" }, { "ErrorEntity": { "Code": "BadRequest", "Message": "Encountered an error (ServiceUnavailable) from host runtime." } } ], "Innererror": null }

@3mard
Copy link

3mard commented Aug 22, 2020

@marcin-dudek

I got around this by using a bash script that basically did
FUNCTION_KEY=$(az rest --method post --uri "$FUNCTION_ID/host/default/listKeys?api-version=2019-08-01" | jq -r ". | .functionKeys.default")

@magodo magodo added this to the v2.27.0 milestone Sep 8, 2020
magodo pushed a commit that referenced this issue Sep 8, 2020
@ghost
Copy link

ghost commented Sep 10, 2020

This has been released in version 2.27.0 of the provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. As an example:

provider "azurerm" {
    version = "~> 2.27.0"
}
# ... other configuration ...

@ghost
Copy link

ghost commented Oct 8, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!

@ghost ghost locked as resolved and limited conversation to collaborators Oct 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.