Environment variable definitions no longer survive fleet moves?


#1

Hi folks, for the last months, we’ve been using environment variables to pass certificates and unique IDs to our devices, most of which are running 2.3.0. Our workflow is to bring the device online into a staging fleet, set the environment variables and confirm connectivity, and then move it a production fleet after its baked for awhile. We will frequently move devices from fleet to fleet to make selective deployments, etc.

As of the multi-container update, which is looking to have great potential - our management workflow has sort of fallen over into the ditch, and our fleets are, at the moment “paralyzed”. That’s because every time we move a device, it loses its environment variables and becomes unable to connect to the IoT broker. Worse, some of these environment variables are set during manufacture to indicate the device configuration, which is lost when the device moves.

Weirder still, sometimes even defining the variables in the new fleet does not seem to “take”, and although the variables are listed on the service variables page, the code on the device keeps insisting they are empty.

I’m hoping I’m doing something wrong; is this the intended new behavior of environment variables? I guess I would hope that variables defined for “main” would move to the new “main” if one existed in the destination fleet…

Thanks


#4

Hi @bbargen, thanks for the report. I have reproduced this issue and we will be working on a fix asap. Sorry for any inconvenience this has caused.


#5

Thanks for the quick action @shaunmulligan, and if anyone has a workaround or a “really you should be doing that this way” suggestion in the mean time, it would be welcome :slight_smile: Cheers.


#6

Was this ever resolved? I am still struggling with this same issue.


#9

Hi @freako987, it should be resolved, and the way it works now is the following:

  • Device Service Variables don’t survive application move, as they are tied to a service, and that service is tied to the application. The idea being that one service in one application is generally different from another service in another application, and can’t tie them together reliable
  • on the other hand we introduced Device Variables, which are tied to devices, and thus moving between applications it stays with the device. They are exposed to all services on the device.

Which type of env var were you trying to set? And does this help to resolve your issues?


#10

Right now the issue is with Mircoservices and Essentials applications.

  • Essentials -> Essentials retains the variables/works as expected.
  • Essentials -> Microservice does NOT retain variables.

I haven’t tried Microservices -> Microservices yet. The variables are created using v1 of the API with the following code:

async function setEnvVar (resinId: number, name: string, value: string) {
 await api.post('https://api.resin.io/v1/device_environment_variable', {
   device: resinId,
   env_var_name: name,
   value: value,
 })
}

Thanks for the quick response.


#11

And we are trying to set device variables.


#12

Okay, we’ll try to reproduce as well, thanks for the extra details!


#15

Hi @freako987, sorry for the delay getting back to you!

I think I found the issue, and that’s that you are using the v1 API call for that endpoint, not the current v4. Switching to v4 above should have the right behaviour as much as I can tell (and as I tested so far):

In detail, the problem is:

  • the v1 does not know about multicontainer environments, and does not know about actual device env vars, but those vars are like the service env vars in the multicontainer environment.
  • thus your call creates a service env var, for the main service, that is the default for Essential apps that can have only a single service
  • moving the device to a multicontainer-enabled Microservices app, the services will have a different name, thus the service env var will be lost

This all explains what you’ve seen and I can reproduce

The solution is to use the v4 endpoint, as shown in our docs as well:
https://docs.resin.io/reference/api/resources/device_environment_variable/

Not sure how you run your code, though that you have to set the endpoint and API version manually. You could maybe take a look at our Node SDK?

There it would be the matter of using device.envVar (as opposed to the call that sets the service variables, device.serviceVar that is the same that the v1 call falls back onto). There you don’t need to worry about API versions to talk to, it should be handled automatically for you!

Does this help? And sorry for dropping this issue for such a long time :face_with_head_bandage: