Azure / template-specs

MIT License
31 stars 4 forks source link

relativePaths do not work if the template was referenced by a bicep template #74

Open Svessir opened 2 years ago

Svessir commented 2 years ago

I am working on migrating my code base to template-specs and bicep. I have a bunch of modules that have not been migrated to bicep or haven't been published as a template-spec yet but I am still referencing these modules from bicep. The issue is that the relativePath within these modules get completely ignored when I push the bicep artifact as a template-spec, forcing me down the path of a bing bang migration (all or nothing).

Also, though more of a bicep issue: When building a template-spec from a bicep file it would be good for the compiled code to use the relativePath instead of nesting the modules as it would preserve the relativePath of the module referenced from bicep.

alex-frankel commented 2 years ago

Can you provide the bicep and ARM template code that is causing the issue?

Svessir commented 2 years ago

template-spec-issue.zip

Here is an example of the issue.

alex-frankel commented 2 years ago

I think I understand what you are describing. The relativePath property works in two different contexts:

  1. If you are creating a template spec, the powershell and CLI commands will find these references and "package" it all together in the resulting template spec
  2. If you are doing a "traditional" non-template-spec deployment, we will automatically convert the relativePath value to the "uri" equivalent at deployment time. That way, you can "stage" the templates at a public URI and everything will still work and you don't need to re-write your templates.

The way you are deploying this code, this falls into scenario 2, and since the templates are not staged, the template will not be found. So you have a few options:

  1. Publish key-vault-deploy.json as a template spec and consume that in Bicep like so:
    module kv 'ts:<subscriptionId>/<resourceGroupName>/<templateSpecName>/<templateSpecVersion>' = { ... }
  2. Convert key-vault-deploy.json to bicep and use modules for the linked templates. This would require you only to convert key-vault-deploy. You should still be able to use the JSON templates for both key-vault.template.json and naming.template.json. Here is a quick decompile with some cleanup:
param nameConfig object
param location string = resourceGroup().location

var namingDeploymentName = 'value'
var deploymentName = 'value'
var resourcesSuffix = 'kv'

module naming 'naming.template.json' = {
  name: namingDeploymentName
  params: {
    environment: nameConfig['environment']
    location: location
    prefix: nameConfig['prefix']
    resource: resourcesSuffix
    system: nameConfig['system']
    app: nameConfig['app']
  }
}

module kv 'key-vault.template.json' = {
  name: deploymentName
  params: {
    location: location
    name: naming.outputs.name
  }
}

output id string = kv.outputs.id

Do either of those work for you?

Btw, I'm a little confused as to what you are trying to do with the resource2 directory. The relativePath is always relative to the current file, so I wouldn't expect that to work no matter how you are deploying.

Svessir commented 2 years ago

I am currently doing what you described in solution 1. That is, convert everything to template specs and that works of course.

What I was trying to show with resources2 was the following. I have the main.json in the root directory which is referencing the key-vault-deploy.json as a module within the resources directory where within the module is referencing via relativePath. If you would run az bicep build -f main.bicep you would get main.json in the root folder. Since bicep compiles the modules into a single file then the relativePaths of the key-vault-deploy.json become invalid as they are now referencing from the root folder. That is why I tried to correct for that in the resources2 directory and main2.json as I thought it was not just picking it up due to the invalid relativePath after the build. But it is not a good solution as it will break any links between files that are not key-vault-deploy.json