Separation of Duties

Introduction

So far, in our discussion of Terraform we have not touched on the concept of permissions and governance. When we execute Terraform “apply” command, it is executed in the context of a single user. This that the current user has all the appropriate permissions required on all the resources referenced. However, it is rarely the case in a real-work environment that a single user will have all the permissions required to deploy an entire application with all of the security and network aspects.

Note: we are using the term “User” here in a general sense. Most clouds also offer instance-based permission models for automation, but the basic principle is the same - a single instance needs all the permissions to support an “apply” command.

Most enterprises have separate teams to manage the core network, create VCNs, apply and change security policies, etc. However, not only may there be different teams for different environments, but the governance model may differ between environments; while a developer needs a broad set of permissions to change routers and networks, in a production environment, these will almost certainly be restricted to a secure administration user.

For these reasons, the emerging best practice is for any significant deployment in the cloud to segregate those resources which require special administration privileges into different Terraform scripts. For example, where a deployment changes the organization’s core routing tables, these would not be bundled in with the application deployment.

Splitting up the deployment scripts into smaller, more discrete units also helps speed up the development cycle. While the network and security basics may be deployed only once, there will likely be many deployments of the core application. This is especially true in an agile or CI/deployment where application resources may be routinely deployed and destroyed as part of the daily CI/CD process.

Landing Zones

If we take this concept a little further, we will see that there are a number of aspects that will be shared across all deployments in your overall cloud estate. This includes :

Collectively, these have come to be known as a “landing zone”, but they are, in effect, establishing a set of broad shared services across all application deployments and workloads. The design and deployment of a landing zone is a broad topic which we will cover in much more detail later.

The relevance at this point of the Terraform discussion is that any deployment used within an Infrastructure-as-code context must be run as a single user in each environment. Each environment may have different user to run the Terraform apply to give protection between environments, but it needs to be a single user.

The impact of this is that your Terraform must be split into discrete deployments in line with your organisations governance and permissions structure. Remember that the target environments will include a production environment, and so, for scripts to be reusable across all environments, they have to support the maximum separation of duties - not just those in the development environment.

In general, we would recommend that all aspects that require special administrative privileges should be included in the “landing zone” and implemented through managed change control processes.

In OCI, we recommend the use of “Instance Principals”. This is an identity management capability where a specific instance (virtual machine) can be designated as a “principal” within identity management and so can inherit security permissions. This enables automated CI/CD processes without the need to hard-coding user IDs or sensitive credentials.

Cross-environment protection

Even in a development environment, it’s possible to do some costly damage with Terraform. Running a “destroy” command in the wrong directory could impact your colleagues in your team, or if there are multiple development teams, it’s possible to make someone else’s entire deployment disappear or at least do significant damage.

This is where we introduce the concept of “least privilege”. We have covered this in the Cloud Foundation governance best practices, but it’s worth mentioning here again that it still applies when using Terraform. In fact, as a result of the “power” of Terraform it’s even more important.

As a Terraform developer, you should always be working within a permitted context or position in the governance hierarchy. In OCI, this is the “container” hierarchy.

Our strong recommendation is that a compartment maps to a single set of Terraform scripts. This result is that everything within that container is managed in one place. Users can then be given permissions on just those compartments that they are building. The core allocation and hierarchy of compartments is managed by the core admin team managing the landing zone. In this way it should be impossible for any user to destroy a compartment that they are not responsible for.