I'm in the process of building some custom Linux images using HashiCorp's Packer, which will later be deployed to Azure using HashiCorp's Terraform. The VMs created from these images will need to have a set of users created; in this particular case I'm concerning myself with user accounts for employees that may need to ssh into these VMs.

For this kind of configuration, does it make more sense to add these user accounts to the base image in the Packer script, or to add them when the VM is created via Terraform? It seems to me that handling it in Packer makes more sense, but are there reasons not to do it there?

6 Answers 6


I would agree with previous statements: avoid baking users into your base image with Packer. Likewise, you should avoid baking them with Terraform as well. Terraform does not provide a mechanism to perform on-going changes after the server is provisioned. It only has those initial provisioning scripts that get run only one time. If you manage users with Terraform provisioning scripts, those users will never get updated again by Terraform. You might as well be baking these changes into Packer at that point.

I would honestly suggest you venture outside the Hashicorp ecosystem for this task. For on-going changes of machines, this is exactly what a configuration management system is designed for. Something like Anisble, Chef, Puppet, or Salt, real configuration management tools, are best suited for this job.

Packer lets you set a base image to be used by many machines. Terraform maintains the state of your architecture as code. However, what happens when you on-board or off-board new users? Or you need to change their individual SSH keys because they lost their computer? This should not be a code change. Nor would you want something like User secrets stored as code in your Terraform provisioning script.

At my company the stack is: Packer images, Terraform bootstrapping, and Chef management. They work well together. I'll admit, I love putting more things into Packer and Teraform as it makes spin up times quicker. But a good CM tool still has its place in the DevOps world.


I am less familiar with what Azure offers, but other cloud providers offer a way to manage users external to the VMs the provide (normally IAM permissions).

I would not bake user into the system but look for an external way to manage them. This allows you to more easily remove users that leave your company or add new users that join.

If Azure doesn't provide a way I would look at setting up Active Directory or LDAP to manage user permissions to hosts. But I would be shocked if you needed to do this.

Note: Don't confuse infrastructure and data. Users are data, not infrastructure. Data (ie adding a user) should be able to change without changing the infrastructure. If you need to remove a user you do not want to rebuild your whole infrastructure.

  • This would certainly work, but it feels to me like it defeats the purpose of maintaining our infrastructure in code. We're planning on building immutable devices which will be regularly replaced, and we're not talking about 1000s of unique devices, so removing users who've left isn't too big of a worry. Worth keeping in mind, though.
    – cori
    Commented Feb 14, 2018 at 18:40
  • Nevertheless, whether users are considered data or infrastructure, maintaining their provisioning information in "code" allows for review of that information that's more difficult (to my mind, at least, although not impossible) when managing that information elsewhere. And as I mentioned since the device lifecycle will be short, "rebuild your whole infrastructure" isn't as alarming as it otherwise might be.
    – cori
    Commented Feb 14, 2018 at 20:45

I avoid "baking" user accounts into my OS image with Packer unless there is an OS specific need for it. For example, a service or system account that is needed across all of my deployments.

My suggestion is to use a Terraform provisioner to create the user accounts. That way you can change them when deploying the VMs via Terraform without having to create a new Packer image. This also allows you to reuse the same Packer image for different purposes that may have different user accounts.

Ultimately it depends on how your workflow is set up. Do you want to make those changes on the VM image or during the deployment?

  • This is good input, thanks. Some of these accounts are pretty broad-based (for example all the members of the infrastructure team will need ssh and sudo permissions on all devices, so baking them into the base image may make sense).
    – cori
    Commented Feb 14, 2018 at 18:42

I agree with others not to bake user accounts into the OS images. Especially personal user accounts of your infrastructure team should be maintained with a decent user management. There are only very rare circumstances where you want to system/service account to be installed everywhere.


Getting users into the systems is most times easy because people ask for it. Reliably cleaning up obsolete user accounts is the much harder problem because the employees are gone.

Often I get asked by customers whether it's possible with an IAM / login solution to deactivate user accounts everywhere without any delay. So even if you plan to mitigate the user removal issue by defining a short life-time of your VMs it will probably not be short enough for dealing with urgent cases.


I wouldn't introduce another infrastructure tool/CM (like Ansible) just for this purpose, instead of that, I would consider these two options:

  1. If your instance lifecycle is short enough, like maybe you replace instances often with recently built images with Packer, you can make use of "user data" of your EC2 instances or launch configurations on your Terraform configuration to describe your users. Next time your instances are launched, your changes will be applied. I think this is the simplest option for a small company, yet might not be suitable for all environments for security or lifecycle reasons.

  2. You can make use of an external authentication source like IAM (see: https://github.com/widdix/aws-ec2-ssh) or LDAP.


Just to add to the existing answers a bit, for "system" users, or users that applications run as, packer would be a fine option, as would using a Terraform provision, or Ansible directly.

For human users, I'd highly suggest using something like FreeIPA. FreeIPA does all the heavy lifting in regards to setting up LDAP, Kerberos, sudo rules, general access rights, all with a shiny web interface.

I mean, do you really want to rebuild the servers if someone wants to change their password?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.