Permissions

knitr::opts_chunk$set(engine.opts = list(zsh = '-i'))

It’s very tempting to get straight into creating infrastructure, however we want to make sure that security is built-in from the start. Applying everything using a super user account is not (generally) a privilege we’re going to have in the real world.

For each of the cloud providers, what we want to do is set up a ring-fenced area for our study. Then when we use Terraform we will authenticate using an account that only has access to this area. This limits our blast radius to an area where we can create and destroy resources without worrying about accidentally “bringing down production”.

The selections below are our foundational set up before we start to use Terraform. This chapter is unique in thatg we’ll be solely using each cloud provider’s CLI tool to do the configuration. Subsequent chapters will almost always use Terraform, unless there’s something that it can’t do.

AWS

Of the three cloud providers, it seems AWS (and I am happy to be corrected here) is the most diffucult to ring-fence access in. As you’ll see below, Azure have resource groups and GCP has projects that we can limit a service account to, whereas AWS does not have this. Instead, we’ll use tags in conjunction with access policies to limit our access.

In our first step, we’ll create a ‘study’ user, a ‘study’ group, and add that user to the group:

# Create the user, the group, and add the user to the group
aws iam create-user --user-name study --path "/users/"
aws iam create-group --group-name study --path "/groups/"
aws iam add-user-to-group --user-name study --group-name study

## {
##     "User": {
##         "Path": "/users/",
##         "UserName": "study",
##         "UserId": "AIDA5BTYAKZGHYUDEE7RQ",
##         "Arn": "arn:aws:iam::896826103372:user/users/study",
##         "CreateDate": "2021-07-22T02:32:33Z"
##     }
## }
## {
##     "Group": {
##         "Path": "/groups/",
##         "GroupName": "study",
##         "GroupId": "AGPA5BTYAKZGH4YGS3BLB",
##         "Arn": "arn:aws:iam::896826103372:group/groups/study",
##         "CreateDate": "2021-07-22T02:32:34Z"
##     }
## }

The ‘path’ variable I’ve specified is optional, but it allows us to structure the users and groups we create. This can help when you’re referring to groups or users using their arn. For example you could refer to all groups under ‘/groups/business_unit_a/’ using the arn arn:aws:iam:<account_id>:group/groups/business_unit_a/*.

Now we generate an access key that we’ll use to authenticate. I write it out to a file, but I’ve also made sure I add the line "*.priv.txt" to my .gitignore file to I don’t accidentally advertise my IAM key to the whole world.

We then create a new profile using the AWS CLI using the command aws configure --profile terraform. In all subsequent Terraform code you will see the following at the top in the provider configuration:

This results in Terraform using the specified AWS CLI profile, and thus will use the IAM access key associated with our ‘study’ user.

We won’t go into the specific IAM policies that we will apply at each stage in this section. We’ll define and discuss the required policies at the start of each chapter.

Azure

Azure makes things easier for us, we:

  • create a resource group that will contains all of our resources

  • Create a ‘Service Principal’ which we will use to authenticate

  • Add this service principal to the resource group as a contributer.

First off, let’s create our resource group:

Next we create the service principal. We’ll use a self signed X509 certificate to authenticate. The below openssl commands:

  • Create the RSA key and certificate signing request

  • Sign the CSR to create our certificate

  • Combine the key and certificate into a PKCS12 file (with no

    password)

We’ll store these files outside of this repository in a home directory.

With our self-signed certificate, we can create our service principal in Azure:

Here’s what the response looks like. As we’re authenticating using a certificate, none of these values are considered secret.

We now add this service principal as a contributor to the ‘study’ resource group.

Now within the provider section of the Terraform code we can add the following to authenticate as the ‘study’ service principal:

GCP

GCP also makes things relatively easy for us. We will:

  • Create a ‘project’, much like the Azure ‘resource group’.

  • Create a service account.

  • Generate and save the keys.

First up, we create the project and enable it to bill. At this point, the ‘gcloud’ CLI is authenticated with a super user account.

Next, we create the service account, generate and then save the authentication keys.

You can see the returned structure here, with the key ID and key redacted:

We then authorise access to GCP using this service account. This allows the ‘gcloud’ CLI tool (and thus Terraform, which uses this under the hood) to make requests using the service account:

Finally, we switch the gcloud CLI tool to use our service account to make requests, rather than the super user account we were using previously:

Now when we use Terraform with a GCP provider, it will make authenticate using the current active account.

Last updated

Was this helpful?