2021-12-13 13:36:42 -08:00
# Managing on-prem service account keys by uploading public keys
2021-12-06 08:02:56 -08:00
2021-12-13 13:36:42 -08:00
When managing GCP Service Accounts with terraform, it's often a question on **how to avoid Service Account Key in the terraform state?**
2021-12-15 09:26:44 -08:00
This example shows how to manage IAM Service Account Keys by manually generating a key pair and uploading the public part of the key to GCP. It has the following benefits:
2021-12-13 13:36:42 -08:00
- no [passing keys between users ](https://cloud.google.com/iam/docs/best-practices-for-managing-service-account-keys#pass-between-users ) or systems
2021-12-15 09:26:44 -08:00
- no private keys stored in the terraform state (only public part of the key is in the state)
2021-12-13 13:36:42 -08:00
- let keys [expire automatically ](https://cloud.google.com/iam/docs/best-practices-for-managing-service-account-keys#key-expiryhaving )
2021-12-06 08:02:56 -08:00
## Running the example
2022-01-11 03:42:00 -08:00
Clone this repository or [open it in cloud shell ](https://ssh.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fcloud-foundation-fabric&cloudshell_print=cloud-shell-readme.txt&cloudshell_working_dir=examples%2Fcloud-operations%2Fonprem-sa-key-management&cloudshell_open_in_editor=cloudshell_open%2Fcloud-foundation-fabric%2Fexamples%2Fcloud-operations%2Fonprem-sa-key-management%2Fvariables.tf ), then go through the following steps to create resources:
2021-12-13 13:36:42 -08:00
Cleaning up example keys
```bash
rm -f /public-keys/data-uploader/
rm -f /public-keys/prisma-security/
```
Generate keys for service accounts
```bash
mkdir keys & & cd keys
openssl req -x509 -nodes -newkey rsa:2048 -days 30 \
2021-12-06 08:02:56 -08:00
-keyout data_uploader_private_key.pem \
-out ../public-keys/data-uploader/public_key.pem \
-subj "/CN=unused"
2021-12-13 13:36:42 -08:00
openssl req -x509 -nodes -newkey rsa:2048 -days 30 \
2021-12-06 08:02:56 -08:00
-keyout prisma_security_private_key.pem \
-out ../public-keys/prisma-security/public_key.pem \
-subj "/CN=unused"
2021-12-13 13:36:42 -08:00
```
Deploy service accounts and keys
```bash
cd ..
terraform init
terraform apply -var project_id=$GOOGLE_CLOUD_PROJECT
```
2021-12-06 08:02:56 -08:00
2021-12-13 13:36:42 -08:00
Extract JSON credentials templates from terraform output and put the private part of the keys into templates
```bash
2021-12-15 02:07:22 -08:00
terraform show -json | jq '.values.outputs."sa-credentials".value."data-uploader"."public_key.pem" | fromjson' > data-uploader.json
terraform show -json | jq '.values.outputs."sa-credentials".value."prisma-security"."public_key.pem" | fromjson' > prisma-security.json
2021-12-06 08:02:56 -08:00
2021-12-13 13:36:42 -08:00
contents=$(jq --arg key "$(cat keys/data_uploader_private_key.pem)" '.private_key=$key' data-uploader.json) & & echo "$contents" > data-uploader.json
contents=$(jq --arg key "$(cat keys/prisma_security_private_key.pem)" '.private_key=$key' prisma-security.json) & & echo "$contents" > prisma-security.json
```
2021-12-06 08:02:56 -08:00
2021-12-13 13:36:42 -08:00
## Testing the example
Validate that service accounts json credentials are valid
```bash
gcloud auth activate-service-account --key-file prisma-security.json
gcloud auth activate-service-account --key-file data-uploader.json
```
2021-12-06 08:02:56 -08:00
2021-12-13 13:36:42 -08:00
## Cleaning up
```bash
terraform destroy -var project_id=$GOOGLE_CLOUD_PROJECT
```
2021-12-06 08:02:56 -08:00
2021-12-30 01:56:19 -08:00
2021-12-06 08:02:56 -08:00
<!-- BEGIN TFDOC -->
2021-12-20 23:51:51 -08:00
2021-12-06 08:02:56 -08:00
## Variables
| name | description | type | required | default |
2021-12-20 23:51:51 -08:00
|---|---|:---:|:---:|:---:|
| project_id | Project id. | < code > string< / code > | ✓ | |
| project_create | Create project instead of using an existing one. | < code > bool< / code > | | < code > false< / code > |
| service_accounts | List of service accounts. | < code title = "list(object({ name = string iam_project_roles = list(string) public_keys_path = string }))" > list( object( { … } ) ) < / code > | | < code title = "[ { name = "data-uploader" iam_project_roles = [ "roles/bigquery.dataOwner", "roles/bigquery.jobUser", "roles/storage.objectAdmin" ] public_keys_path = "public-keys/data-uploader/" }, { name = "prisma-security" iam_project_roles = [ "roles/iam.securityReviewer" ] public_keys_path = "public-keys/prisma-security/" }, ]" > [ … ] < / code > |
| services | Service APIs to enable. | < code > list( string) < / code > | | < code > [ ] < / code > |
2021-12-06 08:02:56 -08:00
## Outputs
| name | description | sensitive |
|---|---|:---:|
2021-12-15 02:07:22 -08:00
| sa-credentials | SA json key templates. | |
2021-12-20 23:51:51 -08:00
2021-12-06 08:02:56 -08:00
<!-- END TFDOC -->
2021-12-30 01:56:19 -08:00