The #{each machine in Octopus.Environment.MachinesInRole[JOB-SERVER-MACHINES]}#{Octopus.Machines[machine].Name}#{/each} does not work properly

Hi Octopus Deploy Team,

We had the following setup in our CI:

Environments:

  • QA, UAT
    Roles:
  • APP-SERVER-MACHINES, JOB-SERVER-MACHINES, JOB-SERVER-MACHINES-QA, JOB-SERVER-MACHINES-UAT
    Machines:
  • MACHINE1-QA [APP-SERVER-MACHINES, JOB-SERVER-MACHINES, JOB-SERVER-MACHINES-QA]
  • MACHINE2-QA [APP-SERVER-MACHINES, JOB-SERVER-MACHINES-QA]
  • MACHINE1-UAT [APP-SERVER-MACHINES, JOB-SERVER-MACHINES, JOB-SERVER-MACHINES-UAT]
  • MACHINE2-UAT [APP-SERVER-MACHINES, JOB-SERVER-MACHINES-UAT]
  • MACHINE3-UAT [APP-SERVER-MACHINES, JOB-SERVER-MACHINES-UAT]

Now when we use the code below to fetch all JOB-SERVER-MACHINES names, we either get exact #{Octopus.Machines[machine].Name} placeholder or blank value after Octopus Deploy variable substitutions:

#{each machine in Octopus.Environment.MachinesInRole[JOB-SERVER-MACHINES]}#{Octopus.Machines[machine].Name}#{/each}

Here’s the Octopus Deploy Versions…

Octopus Deploy Server version: Octopus 3.3.4
Octopus Deploy Tentacle version: Octopus 3.3.4
PowerShell version: 4.0
.NET Framework version: 4.5
OS version: Windows Server 2012 R2

Anything that is causing this to not function properly?

Thank you!

Hi there,

Thanks for reaching out. This isn’t particularly easy, but there’s ways around it. Before I come up with an approach I need to know: Are you trying to use the machine name in an email step, or are you trying to loop over the machine names to do something fancier from a Powershell step?

The approach to take will vary a lot depending on what you are trying to do, so please try to explain this as much as you can :slight_smile:

Thanks!
Dalmiro

HI Dalmiro,

We are using this in an Octopus Deploy Variable, and we are using this to loop over the machine names so that it can dynamically get the machine name without touching the octopus deploy variables frequently, and by “tagging” the machines via Environments (using roles) without the need to create an Octopus Deploy Release to get the latest snapshot of Octopus Deploy Variables’ values. We also utilized the server roles as an environment identifier too, to test and use the said code, especially in traversing the machines in specific roles.

Let’s say the variable name holding the code is JobMachineServer. We are expecting the code #{each machine in Octopus.Environment.MachinesInRole[JOB-SERVER-MACHINES]}#{Octopus.Machines[machine].Name}#{/each} to get the machine names MACHINE1-QA and MACHINE1-UAT respectively, but we only get empty value and/or #{Octopus.Machines[machine].Name} value, and not the machine names.

Given the setup above, if we deploy to QA environment and we added 3 more machines (let’s say MACHINE3-QA, MACHINE4-QA), if my assumption is correct, all machines, MACHINE1-QA, MACHINE2-QA, MACHINE3-QA and MACHINE4-QA should have the JobMachineServer variable value MACHINE1-QA.

Let me know if you need more clarifications with the scenarios.

Thank you.

Lester

Hi Dalmiro,

Any updates with our inquiry/request?

Is my clarification above sufficient with what we need to accomplish for #{each}?

Thank you.

Lester

We would really appreciate an update on this because we are on a time deadline to get quite a few clients setup.

To clarify, we are attempting to use the foreach snippet within a Library variable set value that is being used to populate an entry in a configuration file. We would like it to dynamically populate the server name based on the role assigned to the server. We have only 1 machine in that role per environment. We expect that it would fill in the machine name, but currently we get a blank value or the unresolved snippet.

ex. value = http://#{each machine in Octopus.Environment.MachinesInRole[JOB-SERVER-MACHINES]}#{Octopus.Machines[machine].Name}#{/each}/

Thank you for your assistance!

Hi,

Deep apologies for the delay here. Somehow this one slipped out of my “to-do” list.

I’ll get back to you by tomorrow morning for sure after I test this a bit.

Thanks,
Dalmiro

Thank you, Dalmiro!

Hi There,

Once again apologies for the delay here. Took me a chunk of my day to think and test this out, but here’s the approach I came up with:

  1. Add a script step with the name “Get Machine Names”(#) that runs from the Octopus Server with this script: https://gist.github.com/Dalmirog/ee1e4a6da28505abc823c06ccc5ec932

On it you’ll have to add values to the variables under the Config section. Super recommended to use a Sensitive variable for the API Key.

  1. On your config file you’ll be able to loop over the machine names using the expression
    #{each name in Octopus.Action[Get Machine Names].Output.MachineNames}
       #{name}
    #{/each}

(#) You can pick a different name, but if you do make sure to also change it in (2) in the “each” loop

Hope that helps!
Dalmiro

Thank you Dalmiro!! We’ll see if we can make this work!

Hi Dalmiro,

Thank you for taking the time to come up with this solution. Unfortunately, it doesn’t look like it will work for what we need.

Are there any updates in the pipeline that will allow us to reference other machine names via roles (or the new label functionality) in a variable?

Thanks again!

HI,

I’m afraid the functionality you are mentioning doesn’t exist at the moment.

I’m interested though in understanding why my approach wont work in your scenario. Is there any chance you can send me 2 web.config files:

  • The config file before the variable replacement
  • Another version of that config file manually modified by you with the expected outcome after the deployment.

I think that’ll help me understand what you are looking for a bit better.

Thanks,
Dalmiro

Hi Dalmiro,

We apologize for late reply due to team’s schedule product releases for the past few months. Here’s the sample you requested for:

<?xml version="1.0"?> <?xml version="1.0"?> <?xml version="1.0"?> <?xml version="1.0"?> <?xml version="1.0"?> <?xml version="1.0"?> <?xml version="1.0"?> <?xml version="1.0"?> <?xml version="1.0"?> <?xml version="1.0"?> <?xml version="1.0"?> <?xml version="1.0"?> <?xml version="1.0"?> <?xml version="1.0"?>

Take note that we followed the existing documentation in your application: http://docs.octopusdeploy.com/display/OD/Variable+Substitution+Syntax

As we understood it, we also followed how “truthy” the value is.

Hopefully this helps.

Thank you!

Lester