How to generate unix timestamp in Azure ARM Template - azure

I am creating an ARM template to provision keyvault and it's secrets. I want to generate unix timestamp inside template and supply to nbf and exp attributes which only take integers. Can't find much pointers on this.
i am referring to microsoft documentation https://learn.microsoft.com/en-us/azure/templates/microsoft.keyvault/vaults/secrets
If no solution in ARM template then i need to use powershell to generate and pass it to template which i may not prefer unless there is no other option.

There is no way to generate those with ARM templates. arm templates do not have a way to work with date\time

There is now a function available to generate Unix-style timestamps from an ISO-8601 format.
dateTimeToEpoch('2022-11-17T09:54:13Z')

Use utcNow() function to get Date/Time during deployment time. Note you can use it only in parameter's default value:
"parameters" : {
"todayUtc": {
"type": "string",
"defaultValue": "[utcNow('yyyy-MM-dd')]"
}
}
See: docs

Related

Extracting raw (non string) parameter values from terraform using terraform-config-inspect

I'm trying to generate json from terraform modules using terraform-config-inspect (https://github.com/hashicorp/terraform-config-inspect).
Note: Started with terraform-docs but then found what it uses underneath and it's terraform-config-inspect library.
The problem is that I want to go beyond what terraform-config-inspect provides out of box at the moment:
As an example, I want to get the name of aws_ssm_parameter resource.
For example, I have resource like this:
resource "aws_ssm_parameter" "service_security_group_id" {
name = "/${var.deployment}/shared/${var.service_name}/security_group_id"
type = "String"
value = aws_security_group.service.id
overwrite = "true"
tags = var.tags
}
and I would like to extract the value of the name parameter but by default it does not output this parameter. I tried to hack the code by modifying resource schema and other parts but ended up in getting empty string instead of name value or error because it contains parts like ${var.deployment}.
When I set it to plain string then my modified code returns what I expect
"aws_ssm_parameter.service_security_group_id": {
"mode": "managed",
"type": "aws_ssm_parameter",
"name": "service_security_group_id",
"value": "/test-env/shared/my-service/security_group_id",
"provider": {
"name": "aws"
}
}
but in normal case it fails with the following error
{
"severity": "error",
"summary": "Unsuitable value type",
"detail": "Unsuitable value: value must be known",
...
}
I know that I could build something totally custom for my specific use case but I hope there is something that could be re-used :)
So the questions are:
Is it somehow possible to take the real raw value from terraform resource so I could get "/${var.deployment}/shared/${var.service_name}/security_group_id" in json output?
Maybe some other tool out there?
Thanks in advance!
Input Variables in Terraform are a planning option and so to resolve them fully requires creating a Terraform plan. If you are able to create a Terraform plan then you can find the resolved values in the JSON serialization of the plan, using steps like the following:
terraform plan -out=tfplan (optionally include -var=... and -var-file=... if you need to set particular values for those variables.
terraform show -json tfplan to get a JSON representation of the plan.
Alternatively, if you've already applied the configuration you want to analyse then you can get similar information from the JSON representation of the latest state snapshot:
terraform show -json to get a JSON representation of the latest state snapshot.
As you've seen, terraform-config-inspect is only for static analysis of the top-level declarations and so it contains no functionality for evaluating expressions.
In order to properly evaluate expressions here without creating a Terraform plan or reading from a Terraform state snapshot would require reimplementing the Terraform Core runtime, at least to some extent. However, for this particular expression (which only relies on input variable values) you could potentially use the HCL API directly with some hard-coded placeholder values for those variables in order to get a value for that argument, derived from whatever you happen to have set var.deployment and var.service_name to in the hcl.EvalContext you construct yourself.

ARM template outputs

I see many templates online using primaryEndpoints ouput parameter in ARM templates, but I am not sure how they actually found it as it's not mentioned in the docs. What is the best way to find out the available outputs for a resource?
one of the way is to output the whole object with all properties and values.
"outputs": {
"myObject": {
"type": "Object",
"value": "[reference(parameters('myResources'))]"
}
you can also use resource explorer to browse resources that are provissioned

How to use an Azure Arm Template Output in a variable?

I'm trying to solve a problem I'm having with an Azure ARM template, whereby I need to capture the output of a queried resource in my ARM template, then in that same template, feed that output into a variable / inject that output into a script on another resource that depends on it.
An example -
"outputs":{
"downloadLocation": {
"type": "string",
"value": "[reference(resourceId('randomResource', variables('ResourceName'))).downloadLocation]"
}
}
And
variables: {
"downloadLocation": "[outputs('downloadLocation')]"
}
This variable is then referenced in one of the resources that depends on the source of the queried output.
The downloadLocation can't be formatted in anyway, it contains several signatures and unpredictable strings.
FYI - the below code stops the arm template from being used, by producing the error 'The template function 'outputs' is not valid.'
I'm not locked to storing it as an output, I just need to be able to use that value in another resource - however it's achieved!
The only other route I know would work, but I don't want to explore yet, is that the output could be stored in a file somewhere, then a subsequent script picks it up and injects it into a second ARM template.
If there is a way to use this please let me know, it would help me out significantly!
Thanks
I have found the solution.
The reference function can be called when inside a resource field. So I've had to use reference function as seen above, but it can't be stored in a variable or parameter, it instead needs to be called directly in the resource that's requiring it. Which in this case was the osProfile - customData field.

Can I dynamically generate parameters in Azure templates?

AFAIK, all the parameters have to be defined in the parent template right from the start. Is it possible to generate parameters dynamically at all, such as looping n times to generate n name fields?
This shows how parameters are defined in templates. Note that none of the parameters are created dynamically.
You can use parameters that depend on parameters to emulate something like that:
"parameters": {
"first": {
"type": "string",
"defaultValue": "lol"
},
"second": {
"type": "string",
"defaultValue": "[concat('not_so_', parameters('first'))]"
}
}
would give you value of not_so_lol for the first parameter.
You another option is to create variables that take values depending on the parameter:
"parameterOne": "defaultValue": x, - I'm lazy to type out proper definition in json.
...
"option-x": "something"
"option-y": "something-else"
"result": "[variables(concat('option-', parameters('parameterOne')))]"
so this is basically an If statement in ARM template. the value of the result variable equals to "[variables('option-x')]" or "[variables('option-y')]", depending on your input.
Another (a bit more complex option) is to use deployments outputs. So an example would be, you create a deployment filled with different outputs needed by you (basically you create a pool of constants), and after that, you can reference that deployment outputs in all of your templates (given they reside in the same subscription, but you can create that deployment in all of the subscriptions). that would basically create a pool of constants you can get needed value based on the current value.
"something": "[reference(concat('resourceGroupName', 'Microsoft.Resources/deployments/', parameters('deploymentName')),'2015-01-01').outputs]",
The last (most complex) option is to construct needed stuff on the fly, using nested templates. That's a bit too much to get through in an answer, but I'll just say that in this case you need to use nested templates as aggregator\transformator, where you feed values in and get desired output. This is pretty advanced stuff, but worth knowing. This would be a good example (for starters).
According to your description, we can use uniqueString() to achieve generate parameters dynamically. This function is helpful when you need to create a unique name for a resource.
More information about uniqueString, please refer to this link.

Azure ARM Template variable: Get Subscription name property

Is there a way to get the current subscriptions name into a variable?
Something like this:
"variables": {
"Purpose": "[subscription().SubscriptionName]"
},
Visual Studio says "A property of 'subscription' must be one of the following: id, subscriptionId, tenantId." So the above won't work.
I've also found some examples of the "reference" function and tried to use it thus:
"variables": {
"SubName": "[reference('/subscriptions/subscription().subscriptionId','2015-01-01').outputs.name.value]"
},
But when calling the template it errors with:
function 'reference' is not expected at this location
I'm not sure where I should put it and how I get it into a variable.
In PowerShell, I could do this:
(Get-AzureRmSubscription).subscriptionname
For the sack of interest, we have several subscriptions. The subscription name contains a 3 digit "short code" that is used in the naming of resource groups within the given subscription. It serves no purpose other than make it easier to pinpoint what belongs to what. It is part of our naming convention to help admins (who aren't particularly familiar with Azure) easily see what resources are where. I know there are other ways like RBAC etc, but Microsoft's incessant credential cookie capture doesn't lend itself to logging in with different credentials to different subscriptions.
Thanks
W.
At the time of writing this answer (2016 Oct 16) I'm afraid you can't.
According to the docs, this is what subsbscription() returns:
{
"id": "/subscriptions/#####",
"subscriptionId": "#####",
"tenantId": "#####"
}
So you should expect failing on subscription().SubscriptionName.
In the same doc I linked, there is a discussion around this in the comments section, see comment #2694777590 where a Microsoftie say:
Ok - I've added a bug to add the name attribute to the subcription() expression.
this was 2016 June 6, So I guess it's on the way.
As a workaround, you could inject the subscription name from the thing that is executing the template. For example if it's PowerShell you could do
$subName = (Get-AzureRmSubscription).subscriptionname
New-AzureRmResourceGroupDeployment ... -SecscriptionName $subName
Also, I don't know what's the purpose of that string manipulation based on subscription name you talked about, but if is to create subscription scoped unique names, a good practice is to use uniqueString(subscription().subscriptionId) as part of the name.
The subscription() now does have an additional attribute displayName, according to documentation.
The following should work for you:
"variables": {
"Purpose": "[subscription().displayName]"
}
You should be able to use:
subscription().displayName
(I'll get a bug filed on the VS behavior)
I was able to get subscription().subscriptionId to work in a variable my template.
I think this error you are seeing is a result of how Azure reads the template. Based on Microsoft's reference documentation, references cannot be used in variables:
Remarks
The reference function derives its value from a runtime state, and therefore cannot be used in the variables section.
I got the same function 'reference' is not expected at this location until I moved my actual reference call into the body of the template.

Resources