Azure / template-specs

MIT License
31 stars 4 forks source link

RelativePath for nested template not resolving #51

Closed brwilkinson closed 3 years ago

brwilkinson commented 3 years ago

I have 3 tiers in my deployments

templates-deploy --> templates-base --> templates-nested * roleAssignmentsALL.json is in this directory

I switched over to using RelativePath, however I cannot see a way to move from the template-base to reference the templates-nested.

This is my flat structure

image

image

The first level works fine... i.e. the deploy calling the base, however I am having an issue with the next level.

if I have this in relative path, it get the output below. . . which I would expect.

image

image

Then doing this... I get this the output below. . . which I would expect

image

image

However I cannot figure out a way to go any deeper ?

i.e.

image

still shows this ?

image

The extra ../ is being ignored ? I could not think of any other syntax to try ?

stuartko commented 3 years ago

Based on the hierarchy I see from the screenshots, this is by design if your linked templates are not within the directory of your master/main template or any of its subdirectories. For security reasons, we do not allow references to files in directories outside of your master template directory hierarchy.

To confirm this is the issue you're facing, I'll send you an additional mail with more questions.

brwilkinson commented 3 years ago

just linking to this other discussion #52 . . . to ensure this is an inclusive conversation between deploying from storageURI and deploying from TemplateSpecs.

snarkywolverine commented 3 years ago

I'm not 100% confident I'm following the file structure you laid out, but here's my best understanding:

templates-deploy [contains mainTemplate.json] templates-nested [contains roleAssignmentsAll.json]

In mainTemplate.json, you are specifying a nested deployment in the json using the notation above (I'll use shorthand here): templateLink.RelativePath = "../templates-nested/roleAssignmentsAll.json"

And then deploying with a single URI: templateLink.Uri = "https://www.myfavoritestorageaccount.com/importantFiles/templates-deploy/mainTemplate.json"


@stuartko is correct that TemplateSpecs does not support this 'upward' hierarchy; it only works in a flat hierarchy (all templates in the same folder), or a nested hierarchy (where the 'entry point' / main template is in one directory, and the nested templates have child folder[s]).


If you are doing this purely for uploading via URI, there is a bit of a trick that can make this pattern work; you can leverage relative path for deployment of the main template. Instead of using a single URI as above, you can break it up:

templateLink.Uri = "https://www.myfavoritestorageaccount.com/importantFiles" templateLink.RelativePath = "templates-deploy/mainTemplate.json"

Note that this is explicitly blocked for Template Specs - users should think of a template spec as a module (where the nested templates are 'private' to the TS). But, for just navigating around the hierarchy with URI-based deployments, this should work.

brwilkinson commented 3 years ago

I plan to have this working for both Template Specs and also URI based deployments, since I will do dev/test against storage, then I will use Template specs with the exact same templates for non dev/test deployments.

Anything new will be added and tested to the templates against storage and this cycle will continue daily, once the templates are working as expected and tested they will be converted to template specs.

There are 3 layers here, the first 2 work fine, the 2rd layer fails.... however the it should work, since it's at the same level on the file system relative to the first layer vs second layer.

@snarkywolverine perhaps a call would help, so I can also understand what you mentioned about the workaround etc. Not sure if you were implying to pass in both URI and Relative path to my nested deployments ?

brwilkinson commented 3 years ago

I am deploying this:

https://acu1brwaoag1saglobal.blob.core.windows.net/acu1-aoa-stageartifacts-benwilk/templates-deploy/00-azuredeploy-sub-InitialRG.json

In this case it's kicking off 2 nested deployments that you can see below . . . one of them creates RG's the other applies Role Based Access Control role assignments.

image

So "00-azuredeploy-sub-InitialRG.json" has two deployments that reference these templates, that are in "templates-base"

These use relativePath on the deployments.

    "DeploymentInfoObject": {
      "RG": "../templates-base/00-azuredeploy-sub-RGs.json",
      "RBAC": "../templates-base/00-azuredeploy-sub-RGRoleAssignments.json"
    }

above works as expected

So now I am able to look in the "00-azuredeploy-sub-RGRoleAssignments.json" 'templates-base' deployment . .

image

So in this template 00-azuredeploy-sub-RGRoleAssignments.json it actually calls other worker templates or what I refer to as nested-templates.

image

The template it's calling is templates-nested/roleAssignmentsALL.json and it's just another deployment, exactly the same as the two above this that kicked it off.

However when it attempts to resolve the path of that template when using RelativePath it fails to find the template.

The path to find the file is not taking into account that it's been deployed as a child deployment. It's two levels nested, however the code doesn't know this, so it looks for the templates thinking it's at the root level, not nested (child level scope).

i.e.

So on the relativePath I need to try and locate the template that I want to deploy, in the templates-nested directory

if I have ./templates-nested/filename.json I get the following..

image

image

notice how it shows /templates-deploy/templates-base/templates-nested/filename.json ???

Above is where it's looking for the template... however why does it look there I used ./nested-templates on my RelativePath?

I think if we can explain why it's looking here, we an figure out the issue ?!! this one picture should be the most helpful.

image

So now I try ../nested-templates on my RelativePath . . .

image

Now it's look for my template on this path . . so adding ../ seems to be working to find my file. I've gone up 1 level relative to the ROOT of the storage account i.e. my base URI... if I can get up 1 more level it will actually find my file.

image

So I will try 2 get to the root, I think the syntax should be ../../templates-nested to try to go up two levels

image

still shows the exact same as ../ which was the previous case above ? So currently I am two levels deep in my deployment, however there is no syntax that allows me to get back to the storage URI root.

image

Currently on these nested-templates I have to still use the URI, which I just inject in via a custom parameter to make it work. However I really don't want to do this, I just want to be able to reference my file in the storage via Relative Path.

image

This is a small/subtle issue... if I can deploy from templates-deploy and easily hit a template in templates-base I don't see any reason as far as security goes as accessing the other directory called 'templates-nested' . . . Infact I can actually deploy directly from templates-base and use relativepath on the child deployment against templates-nested if I skip the top level deployment.

So in short I just need a way to traverse from being 2 levels deep in a deployment path back up to the root level. Currently I actually go 4 levels deep in my deployments (there maybe a scenario in the future that would require 5 levels of depth), not just 3 shown here, however all templates are in those directories.

Let me know if a call or video would help to describe the scenario better 🙂

snarkywolverine commented 3 years ago

Can you share a correlation ID of a deployment that is more recent than the screenshots from 2/15? I'd like to take a look at the logs.

Also, since you want this to be deployed via TemplateSpec anyway - have you tried creating a template spec with this hierarchy?

brwilkinson commented 3 years ago

hey @snarkywolverine I have a few separate issues for tracking the Template Specs items.

e.g. #52

Here are 3 sample deployments from just now... just ping me if you want more

  1. The tracking Id is '1c853811-e167-4c67-8b80-1b660b82cfa4'. with ../ with this: "relativePath": "../templates-nested/roleAssignmentsALL.json",

it's looking for: --> acu1-aoa-stageartifacts-benwilk/templates-deploy/templates-nested/roleAssignmentsALL.json

 | 11:14:17 AM - Error: Code=InvalidContentLink; Message=Unable to download deployment content from
 | 'https://acu1brwaoag1saglobal.blob.core.windows.net/acu1-aoa-stageartifacts-benwilk/templates-deploy/templates-nested/roleAssignmentsALL.json?sv=2019-07-07&sr=c&sig=%2FmcHD1uZ&sp=r'. 
  1. The tracking Id is '9bca148e-a8c9-430f-bd0d-2c78d4f2b8d9'. with ./ with this: "relativePath": "./templates-nested/roleAssignmentsALL.json",

it's looking for: --> acu1-aoa-stageartifacts-benwilk/templates-deploy/templates-base/templates-nested/roleAssignmentsALL.json

 | 11:16:48 AM - Error: Code=InvalidContentLink; Message=Unable to download deployment content from
 | 'https://acu1brwaoag1saglobal.blob.core.windows.net/acu1-aoa-stageartifacts-benwilk/templates-deploy/templates-base/templates-nested/roleAssignmentsALL.json?sv=2019-07-08%3D&se=2021-04-16T22%3A16%3A45Z&sp=r'. 
  1. The tracking Id is 'a2ec064b-2e9c-41b7-a122-901c22edbe95'. with ../../ with this: "relativePath": "../../templates-nested/roleAssignmentsALL.json",

it's looking for: --> templates-deploy/templates-nested/roleAssignmentsALL.json

 | 11:22:38 AM - Error: Code=InvalidContentLink; Message=Unable to download deployment content from
 | 'https://acu1brwaoag1saglobal.blob.core.windows.net/acu1-aoa-stageartifacts-benwilk/templates-deploy/templates-nested/roleAssignmentsALL.json?sv=2019-07-07&sr=c&sig=wUIq76%2Bim%3A22%3A25Z&sp=r'. 

--

In order to actually find the file it would need to look for: acu1-aoa-stageartifacts-benwilk/templates-nested/roleAssignmentsALL.json

brwilkinson commented 3 years ago

@snarkywolverine also if it helps I can build you out some repro templates, so you can test deploy via multi level nested deployments yourself.

brwilkinson commented 3 years ago

okay I did the standalone repro code.

https://github.com/brwilkinson/azdeployrecursive

you can just kick off the azdeploy.ps1

it will 1.create the resource group foo3

  1. create the storage account with random guid name
  2. upload the 3 templates to storage: deploy, base, nested
  3. kick off the repo deployment.

Unable to download deployment content from 'https://51d5ccdbc5e64af48431d2.blob.core.windows.net/assets/1deploy/3nested/3nested.json

brwilkinson commented 3 years ago

Closing due to age.