WebApp ARM template with variable number of AppSettings - json

How can you create an ARM template for a web app that can take a varied number of App Settings in a parameters.json file?
I have tried using this approach:
{
"name": "[concat(variables('web_app_name'), '/appsettings')]",
"type": "Microsoft.Web/sites/config",
"apiVersion": "2018-11-01",
"properties": {
"appSetting1": "value1",
"AppSetting2": "value2"
},
"dependsOn": [
"[resourceId('Microsoft.Web/sites/', variables('web_app_name'))]"
]
}
But this wipes my default properties on a WebApp such as APPINSIGHTS_INSTRUMENTATIONKEY, ApplicationInsightsAgent_EXTENSION_VERSION etc. as this doesn't merge with the already existing app settings but overwrites them. There is an issue reported on GitHub: https://github.com/Azure/azure-cli/issues/11718
Then there is some mentioning of using this method: https://kalcik.net/2019/11/21/merge-azure-app-service-app-settings-in-arm-template/
[union(
variables('appServiceBaseConfig'),
variables('appService1'),
json(
concat(
'{\"APPINSIGHTS_INSTRUMENTATIONKEY\":\"',
reference(concat('microsoft.insights/components/', variables('applicationInsightsName')), '2015-05-01').InstrumentationKey,
'\"}')
)
)
]
but this makes my eyes bleed and doesn't even support line breaks and az deployment group validate pukes on it stating that it is not valid json if it is not on one line, which makes this useless.
Any smart work arounds?

Related

How to pass a list as an environment variable to an AWS Lambda function from a JSON config file?

I have a JSON file that is going to contain a number of different lists per client that I am deploying for. These lists are going to serve as container overrides for an ECS task that my Lambda function will be invoking. The JSON config file would look something like this:
{
"clientName": {
"environment": [
{
"name": "name1",
"value": "value1"
}
]
}
}
And my serverless.yml would look something like this:
environment:
CONTAINER_ENVIRONMENT: ${file(serverlessConfig.json):${env:CLIENT_NAME}.environment}
Which results in the following error:
Could not resolve "CONTAINER_ENVIRONMENT" environment variable: Unsupported environment variable format:
[
{
"name": "name1",
"value": "value1"
}
]
I've tried using CloudFormation intrinsic functions such as Fn::Join and Fn::ToJsonString. These both threw an error when trying to run locally using sls invoke local (the errors were the same as the above). After some digging it seems that these functions aren't compatible with the serverless environment property.
The only thing that has worked so far is storing the list as a string in a .env file, but that's not really ideal since these configs could take a number of different environment objects.
Is there any way to get this to work with the setup that I have going?

How do I modify parameters in a Container Overrides section of a Step Functions machine?

I have a Step Functions Machine the definition file of which looks as such:
"ContainerOverrides": [
{
"Name": "Foo",
"Environment": [
{
"Name": "Foo"
"Value": "Bar"
},
],
"Command.$": "States.Array($.Foo,$.Foo,$.Bar,$.Bar,$.Bar)"
}
]
},
that I am trying to rewrite into Typescript (CDK). I've gotten the following few lines.
containerOverrides: [{
containerDefinition: Foo,
environment: [
{ name: 'Foo', value: 'Bar'},
],
command: ['States.Array($.Foo,$.Foo,$.Bar,$.Bar,$.Bar)'],
}],
I'm a bit confused about how to go about this.
When I deploy the above CDK code, I get as output:
"Command": [
"States.Array($.Foo,$.Foo,$.Bar,$.Bar,$.Bar)"
],
My confusion is in regards to the following: The ContainerOverrides method doesn't accept parameters, but I need to modify a parameter (Command.$), so how can I possibly do that? I came across this post where somebody seems to have a similar issue, but when I try to apply the proposed solution, of simply writing
command: JsonPath.arrayAt('States.Array($.Foo,$.Foo,$.Bar,$.Bar,$.Bar)'
I get told that ''Cannot use JsonPath fields in an array, they must be used in objects''
TL;DR The current implementation of EcsRunTask doesn't permit this. The general-purpose CallAwsService construct does.
The EcsRunTask construct is the CDK's implementation of the ECS optimised integration. The construct only accepts an array of strings as override commands. It cannot produce substitutable output like "Command.$": "$.commands" that's needed to read the override command from the execution input. This is a limitation of the CDK implementation, not of the ECS optimized integration itself.
The cleanest solution is to use the CallAwsService construct, which implements the SDK service integration. It requires manual configuration. The API-specific config goes in the parameters prop. The prop is loosely typed as { [string]: any }. It's flexible, but it's your job to provide the expected syntax for the ecs:RunTask SDK call. Here is the relevant bit for your question:
parameters {
Overrides: {
ContainerOverrides: [
{ Command: sfn.JsonPath.array("sh", "-c", sfn.JsonPath.stringAt("$.cmd")), },
],
},
}
It produces the expected command override in the Step Functions task definition:
"Command.$": "States.Array('sh', '-c', $.cmd)"

Room object in Revit files

I followed the instruction in the link below to extract Room objects from Revit models:
https://forge.autodesk.com/blog/new-rvt-svf-model-derivative-parameter-generates-additional-content-including-rooms-and-spaces
I made the changes as instructed and tested the sample Revit file (rac_basic_sample_project.rvt). But, still I don't see the rooms or the viewables (phases). Below is fhe request I post. Am I missing anything?
{
"input": {
"urn": "dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6YzQ4ZDUxNDNhMDRiNDAxNmI3ODYxY2NlMzQ2ZDkyNjdfZmFjaWxpdHlfOTUvZWIyYzMzNDgtNDAxYS00ZjQ3LTgwM2EtMjM1OGYwYmI0YjY2LnJ2dA"
},
"output": {
"destination": {
"region": "us"
},
"formats": [
{
"type": "svf",
"views": [
"3d"
],
"advanced": {
"generateMasterViews": true
}
}
]
}
}
I just tested the feature and I can see the room data:
The JSON payload seems ok, so try checking the following things:
Make sure you use the x-ads-force header (explained in the blog post you linked to); if you had already processed your Revit model before, triggering a new Model Derivative job would not do anything unless you force the translation
Try using another design (and from a newer version of Revit if possible); in my screenshot I'm using one of the official samples for Revit 2020, although I remember being able to get the room data from older samples as well
The room data is only available in certain "viewables" so make sure you're looking at the right one; for my sample project, for example, the room data is not available in the "{3D}" viewable but it is available in the "Working Drawings" viewable

Does config.GetSection not work in Azure Functions? And what is the recommended alternative?

Azure Function with a complex (List of objects) configuration type is working locally (with that complex type in local.settings.json) but fails to read / create list of objects in Azure (with that complex type in Azure Function configuration settings). I'm looking for the recommended / optimal way to support that across both platforms / methods of access.
This works great in my local.settings.json where I use the configuration builder and pull data out like
var myList = config.GetSection("ConfigurationList").Get<List<MyType>>();
however this doesn't seem to work in Azure Functions?? Now I think that is because in local.settings.json it is a json file and looks like
"ConfigurationList" : [ { "Name": "A", "Value": 2 }, { "Name": "B", "Value": 3 }]
while in Azure Functions it is a setting "ConfigurationList" with the value
[ { "Name": "A", "Value": 2 }, { "Name": "B", "Value": 3 }]
(so there isn't really a "section" in Azure Functions?)
It seems like the "easy" solution to this is to just change the .json to be a quoted string and deserialize the string (and then it would work the same in both places); but that doesn't seem like it would be the "best" (or "recommended" solution)
i.e. something like
"ConfigurationList" : "[ { \"Name\": \"A\", \"Value\": 2 }, { \"Name\": \"B\", \"Value\": 3 }]"
var myList = (List<MyType>)JsonConvert.DeserializeObject(config["ConfigurationList"], typeof(List<MyType>));
Which isn't the worst; but makes the json a bit "not as nice" and doesn't "flow" across the two platforms ... if it is what I have to do, fine; but hoping for a more standard approach / recommendation
As I metioned in the comment, on local you can process local.settings.json as a json file, but when on azure, the value in configuration settings is environment variable. There is no section, it just string.
Please notice that only string values are allowed, and that anything nested will break. Learn how to use nest settings on azure web app(azure functon is based on azure app service sandbox, so it is the same.):
https://learn.microsoft.com/en-us/archive/blogs/waws/asp-net-core-settings-for-azure-app-service
For example, if this is the json structure:
{
"Parent": {
"ChildOne": "C1 from secrets.json",
"ChildTwo": "C2 from secrets.json"
}
}
Then in web app, you should save it like this:
(source: windows.net)
Not sure if you are looking something like this , it seems a list but if it is a simple JObject like
"ConfigurationList" : {
"Name": "A",
"Value": 2
}
Then you can declare ConfigurationList:Name , ConfigurationList:Value in the configuration settings of function app

Which file should I keep: .io-config.json or ionic.config.json?

I recently migrated my Ionic app into Ionic Cloud and after running ionic io init in the command-line, I noticed that I end up with two (config?) json files that seem to have the same purpose. However they have different names and I am not sure which one should be kept. The contents are as follows:
.io-config.json
{
"app_id": "id",
"api_key": "key"
}
ionic.config.json
{
"name": "name",
"app_id": "id",
"watchPatterns": [
"www/**/*",
"!www/lib/**/*"
]
}
Which one should be kept?
According to an expert on Ionic's Slack, both files should be kept. They each have their own specific purpose.