Skip to content

Commit fff90c1

Browse files
0x2b3bfa0casperdcl
andauthored
docs: permissions & reference roles (#443)
Co-authored-by: Casper da Costa-Luis <[email protected]>
1 parent fcc25f3 commit fff90c1

File tree

6 files changed

+353
-6
lines changed

6 files changed

+353
-6
lines changed

docs/guides/authentication.md

+38-6
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ page_title: Authentication
44

55
# Authentication
66

7-
Environment variables are the only supported authentication method. They should be present when running any of the `terraform` commands. For example:
7+
Environment variables are the only supported authentication method, and should be present when running any `terraform` command. For example:
88

99
```bash
10-
$ export GOOGLE_APPLICATION_CREDENTIALS_DATA="$(cat service_account.json)"
11-
$ terraform apply
10+
export GOOGLE_APPLICATION_CREDENTIALS_DATA="$(cat service_account.json)"
11+
terraform apply
1212
```
1313

1414
## Amazon Web Services
@@ -17,7 +17,15 @@ $ terraform apply
1717
- `AWS_SECRET_ACCESS_KEY` - Secret access key.
1818
- `AWS_SESSION_TOKEN` - (Optional) Session token.
1919

20-
See the [AWS documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html) for more information.
20+
See the [AWS documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html) to obtain these variables directly.
21+
22+
Alternatively, for more idiomatic or advanced use cases, follow the [Terraform AWS provider documentation](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration) and run the following commands in the [`permissions/aws`](https://github.com/iterative/terraform-provider-iterative/tree/master/docs/guides/permissions/aws) directory:
23+
24+
```bash
25+
terraform init && terraform apply
26+
export AWS_ACCESS_KEY_ID="$(terraform output --raw aws_access_key_id)"
27+
export AWS_SECRET_ACCESS_KEY="$(terraform output --raw aws_secret_access_key)"
28+
```
2129

2230
## Microsoft Azure
2331

@@ -26,17 +34,41 @@ See the [AWS documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli
2634
- `AZURE_SUBSCRIPTION_ID` - Subscription identifier.
2735
- `AZURE_TENANT_ID` - Tenant identifier.
2836

29-
See the [Azure documentation](https://docs.microsoft.com/en-us/python/api/azure-identity/azure.identity.environmentcredential) for more information.
37+
See the [Azure documentation](https://docs.microsoft.com/en-us/python/api/azure-identity/azure.identity.environmentcredential) to obtain these variables directly.
38+
39+
Alternatively, for more idiomatic or advanced use cases, follow the [Terraform Azure provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/azure_cli) and run the following commands in the [`permissions/az`](https://github.com/iterative/terraform-provider-iterative/tree/master/docs/guides/permissions/az) directory:
40+
41+
```bash
42+
terraform init && terraform apply
43+
export AZURE_TENANT_ID="$(terraform output --raw azure_tenant_id)"
44+
export AZURE_SUBSCRIPTION_ID="$(terraform output --raw azure_subscription_id)"
45+
export AZURE_CLIENT_ID="$(terraform output --raw azure_client_id)"
46+
export AZURE_CLIENT_SECRET="$(terraform output --raw azure_client_secret)"
47+
```
3048

3149
## Google Cloud Platform
3250

3351
- `GOOGLE_APPLICATION_CREDENTIALS` - Path to (or contents of) a service account JSON key file.
3452

35-
See the [GCP documentation](https://cloud.google.com/docs/authentication/getting-started#creating_a_service_account) for more information.
53+
See the [GCP documentation](https://cloud.google.com/docs/authentication/getting-started#creating_a_service_account) to obtain these variables directly.
54+
55+
Alternatively, for more idiomatic or advanced use cases, follow the [Terraform GCP provider documentation](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/getting_started) and run the following commands in the [`permissions/gcp`](https://github.com/iterative/terraform-provider-iterative/tree/master/docs/guides/permissions/gcp) directory:
56+
57+
```bash
58+
terraform init && terraform apply
59+
export GOOGLE_APPLICATION_CREDENTIALS_DATA="$(terraform output --raw google_application_credentials_data)"
60+
```
3661

3762
## Kubernetes
3863

3964
Either one of:
4065

4166
- `KUBECONFIG` - Path to a [`kubeconfig` file](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#the-kubeconfig-environment-variable).
4267
- `KUBECONFIG_DATA` - Alternatively, the **contents** of a `kubeconfig` file.
68+
69+
Alternatively, authenticate with a local `kubeconfig` file and run the following commands in the [`permissions/k8s`](https://github.com/iterative/terraform-provider-iterative/tree/master/docs/guides/permissions/k8s) directory:
70+
71+
```bash
72+
kubectl apply --filename main.yml
73+
export KUBECONFIG_DATA="$(bash kubeconfig.sh)"
74+
```

docs/guides/permissions/aws/main.tf

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
terraform {
2+
required_providers {
3+
aws = { source = "hashicorp/aws", version = "~> 4.3.0" }
4+
}
5+
}
6+
7+
variable "aws_region" {
8+
description = "Name of the Amazon Web Services region to use"
9+
}
10+
11+
provider "aws" {
12+
region = var.aws_region
13+
}
14+
15+
resource "aws_iam_user" "task" {
16+
name = "task"
17+
}
18+
resource "aws_iam_access_key" "task" {
19+
user = aws_iam_user.task.name
20+
}
21+
resource "aws_iam_user_policy" "task" {
22+
name = aws_iam_user.task.name
23+
user = aws_iam_user.task.name
24+
policy = data.aws_iam_policy_document.task.json
25+
}
26+
27+
data "aws_iam_policy_document" "task" {
28+
statement {
29+
actions = [
30+
"autoscaling:CreateAutoScalingGroup",
31+
"autoscaling:DeleteAutoScalingGroup",
32+
"autoscaling:DescribeAutoScalingGroups",
33+
"autoscaling:DescribeScalingActivities",
34+
"autoscaling:UpdateAutoScalingGroup",
35+
"ec2:AuthorizeSecurityGroupEgress",
36+
"ec2:AuthorizeSecurityGroupIngress",
37+
"ec2:CancelSpotInstanceRequests",
38+
"ec2:CreateKeyPair",
39+
"ec2:CreateLaunchTemplate",
40+
"ec2:CreateSecurityGroup",
41+
"ec2:CreateTags",
42+
"ec2:DeleteKeyPair",
43+
"ec2:DeleteLaunchTemplate",
44+
"ec2:DeleteSecurityGroup",
45+
"ec2:DescribeAutoScalingGroups",
46+
"ec2:DescribeImages",
47+
"ec2:DescribeInstances",
48+
"ec2:DescribeKeyPairs",
49+
"ec2:DescribeLaunchTemplates",
50+
"ec2:DescribeScalingActivities",
51+
"ec2:DescribeSecurityGroups",
52+
"ec2:DescribeSpotInstanceRequests",
53+
"ec2:DescribeSubnets",
54+
"ec2:DescribeVpcs",
55+
"ec2:GetLaunchTemplateData",
56+
"ec2:ImportKeyPair",
57+
"ec2:ModifyImageAttribute",
58+
"ec2:ModifyLaunchTemplate",
59+
"ec2:RequestSpotInstances",
60+
"ec2:RevokeSecurityGroupEgress",
61+
"ec2:RevokeSecurityGroupIngress",
62+
"ec2:RunInstances",
63+
"ec2:TerminateInstances",
64+
"s3:CreateBucket",
65+
"s3:DeleteBucket",
66+
"s3:DeleteObject",
67+
"s3:GetObject",
68+
"s3:ListBucket",
69+
"s3:PutObject",
70+
]
71+
resources = ["*"]
72+
}
73+
}
74+
75+
output "aws_access_key_id" {
76+
value = aws_iam_access_key.task.id
77+
}
78+
output "aws_secret_access_key" {
79+
value = aws_iam_access_key.task.secret
80+
sensitive = true
81+
}

docs/guides/permissions/az/main.tf

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
terraform {
2+
required_providers {
3+
azuread = { source = "hashicorp/azuread", version = "~> 2.18.0" }
4+
azurerm = { source = "hashicorp/azurerm", version = "~> 2.98.0" }
5+
}
6+
}
7+
8+
provider "azuread" {}
9+
provider "azurerm" {
10+
features {}
11+
}
12+
13+
data "azuread_client_config" "current" {}
14+
data "azurerm_subscription" "current" {}
15+
16+
resource "azuread_application" "task" {
17+
display_name = "task"
18+
owners = [data.azuread_client_config.current.object_id]
19+
}
20+
resource "azuread_application_password" "task" {
21+
application_object_id = azuread_application.task.object_id
22+
}
23+
resource "azuread_service_principal" "task" {
24+
application_id = azuread_application.task.application_id
25+
app_role_assignment_required = false
26+
owners = [data.azuread_client_config.current.object_id]
27+
}
28+
resource "azurerm_role_definition" "task" {
29+
name = azuread_application.task.display_name
30+
scope = data.azurerm_subscription.current.id
31+
permissions {
32+
actions = [
33+
"Microsoft.Compute/virtualMachineScaleSets/delete",
34+
"Microsoft.Compute/virtualMachineScaleSets/delete/action",
35+
"Microsoft.Compute/virtualMachineScaleSets/instanceView/read",
36+
"Microsoft.Compute/virtualMachineScaleSets/networkInterfaces/read",
37+
"Microsoft.Compute/virtualMachineScaleSets/publicIPAddresses/read",
38+
"Microsoft.Compute/virtualMachineScaleSets/read",
39+
"Microsoft.Compute/virtualMachineScaleSets/scale/action",
40+
"Microsoft.Compute/virtualMachineScaleSets/skus/read",
41+
"Microsoft.Compute/virtualMachineScaleSets/start/action",
42+
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/delete",
43+
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/networkInterfaces/ipConfigurations/publicIPAddresses/read",
44+
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/networkInterfaces/ipConfigurations/read",
45+
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/networkInterfaces/read",
46+
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/read",
47+
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/write",
48+
"Microsoft.Compute/virtualMachineScaleSets/vmSizes/read",
49+
"Microsoft.Compute/virtualMachineScaleSets/write",
50+
"Microsoft.Compute/virtualMachines/delete",
51+
"Microsoft.Compute/virtualMachines/read",
52+
"Microsoft.Compute/virtualMachines/write",
53+
"Microsoft.Network/networkInterfaces/delete",
54+
"Microsoft.Network/networkInterfaces/join/action",
55+
"Microsoft.Network/networkInterfaces/read",
56+
"Microsoft.Network/networkInterfaces/write",
57+
"Microsoft.Network/networkSecurityGroups/delete",
58+
"Microsoft.Network/networkSecurityGroups/join/action",
59+
"Microsoft.Network/networkSecurityGroups/read",
60+
"Microsoft.Network/networkSecurityGroups/write",
61+
"Microsoft.Network/publicIPAddresses/delete",
62+
"Microsoft.Network/publicIPAddresses/join/action",
63+
"Microsoft.Network/publicIPAddresses/read",
64+
"Microsoft.Network/publicIPAddresses/write",
65+
"Microsoft.Network/virtualNetworks/delete",
66+
"Microsoft.Network/virtualNetworks/read",
67+
"Microsoft.Network/virtualNetworks/subnets/delete",
68+
"Microsoft.Network/virtualNetworks/subnets/join/action",
69+
"Microsoft.Network/virtualNetworks/subnets/read",
70+
"Microsoft.Network/virtualNetworks/subnets/write",
71+
"Microsoft.Network/virtualNetworks/write",
72+
"Microsoft.Resources/subscriptions/resourceGroups/delete",
73+
"Microsoft.Resources/subscriptions/resourceGroups/read",
74+
"Microsoft.Resources/subscriptions/resourceGroups/write",
75+
"Microsoft.Storage/storageAccounts/blobServices/containers/delete",
76+
"Microsoft.Storage/storageAccounts/blobServices/containers/read",
77+
"Microsoft.Storage/storageAccounts/blobServices/containers/write",
78+
"Microsoft.Storage/storageAccounts/delete",
79+
"Microsoft.Storage/storageAccounts/listKeys/action",
80+
"Microsoft.Storage/storageAccounts/read",
81+
"Microsoft.Storage/storageAccounts/write",
82+
]
83+
}
84+
}
85+
resource "azurerm_role_assignment" "task" {
86+
name = azurerm_role_definition.task.name
87+
principal_id = azuread_service_principal.task.object_id
88+
role_definition_id = azurerm_role_definition.task.role_definition_resource_id
89+
scope = data.azurerm_subscription.current.id
90+
}
91+
92+
output "azure_subscription_id" {
93+
value = basename(data.azurerm_subscription.current.id)
94+
}
95+
output "azure_tenant_id" {
96+
value = data.azurerm_subscription.current.tenant_id
97+
}
98+
output "azure_client_id" {
99+
value = azuread_application.task.application_id
100+
}
101+
output "azure_client_secret" {
102+
value = azuread_application_password.task.value
103+
sensitive = true
104+
}

docs/guides/permissions/gcp/main.tf

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
terraform {
2+
required_providers {
3+
google = { source = "hashicorp/google", version = "~> 4.12.0" }
4+
}
5+
}
6+
7+
variable "gcp_project" {
8+
description = "Name of the Google Cloud project to use"
9+
}
10+
11+
provider "google" {
12+
project = var.gcp_project
13+
}
14+
15+
data "google_project" "current" {}
16+
17+
resource "google_service_account" "task" {
18+
account_id = "task-service-account"
19+
}
20+
resource "google_service_account_key" "task" {
21+
service_account_id = google_service_account.task.email
22+
}
23+
resource "google_project_iam_binding" "task" {
24+
project = data.google_project.current.project_id
25+
role = "projects/${data.google_project.current.project_id}/roles/${google_project_iam_custom_role.task.role_id}"
26+
members = ["serviceAccount:${google_service_account.task.email}"]
27+
}
28+
resource "google_project_iam_custom_role" "task" {
29+
role_id = replace("${google_service_account.task.account_id}-role", "-", "_")
30+
title = replace("${google_service_account.task.account_id}-role", "-", "_")
31+
permissions = [
32+
"compute.acceleratorTypes.get",
33+
"compute.diskTypes.get",
34+
"compute.disks.create",
35+
"compute.firewalls.create",
36+
"compute.firewalls.delete",
37+
"compute.firewalls.get",
38+
"compute.globalOperations.get",
39+
"compute.instanceGroupManagers.create",
40+
"compute.instanceGroupManagers.delete",
41+
"compute.instanceGroupManagers.get",
42+
"compute.instanceGroupManagers.update",
43+
"compute.instanceGroups.create",
44+
"compute.instanceGroups.delete",
45+
"compute.instanceGroups.get",
46+
"compute.instanceTemplates.create",
47+
"compute.instanceTemplates.delete",
48+
"compute.instanceTemplates.get",
49+
"compute.instanceTemplates.useReadOnly",
50+
"compute.instances.create",
51+
"compute.instances.delete",
52+
"compute.instances.get",
53+
"compute.instances.setMetadata",
54+
"compute.instances.setServiceAccount",
55+
"compute.instances.setTags",
56+
"compute.machineTypes.get",
57+
"compute.networks.get",
58+
"compute.networks.updatePolicy",
59+
"compute.subnetworks.use",
60+
"compute.subnetworks.useExternalIp",
61+
"compute.zoneOperations.get",
62+
"iam.serviceAccounts.actAs",
63+
"storage.buckets.create",
64+
"storage.buckets.delete",
65+
"storage.buckets.get",
66+
"storage.multipartUploads.abort",
67+
"storage.multipartUploads.create",
68+
"storage.multipartUploads.list",
69+
"storage.multipartUploads.listParts",
70+
"storage.objects.create",
71+
"storage.objects.delete",
72+
"storage.objects.get",
73+
"storage.objects.list",
74+
"storage.objects.update",
75+
]
76+
}
77+
78+
output "google_application_credentials_data" {
79+
value = base64decode(google_service_account_key.task.private_key)
80+
sensitive = true
81+
}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
set -euxo pipefail
3+
SERVER="$(kubectl config view --raw --flatten --output jsonpath='{.clusters[0].cluster.server}')"
4+
AUTHORITY="$(kubectl config view --raw --flatten --output jsonpath='{.clusters[0].cluster.certificate-authority-data}')"
5+
SECRET="$(kubectl get serviceaccount task --output jsonpath="{.secrets[0].name}")"
6+
TOKEN="$(kubectl get secret "$SECRET" --output jsonpath="{.data.token}" | base64 --decode)"
7+
export KUBECONFIG="$(mktemp)"
8+
{
9+
kubectl config set-cluster cluster --server="https://$SERVER"
10+
kubectl config set clusters.cluster.certificate-authority-data "$AUTHORITY"
11+
kubectl config set-credentials task --token="$TOKEN"
12+
kubectl config set-context cluster --cluster=cluster --user=task
13+
kubectl config use-context cluster
14+
} >/dev/null
15+
cat "$KUBECONFIG"
16+
rm "$KUBECONFIG"

docs/guides/permissions/k8s/main.yml

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
apiVersion: v1
2+
kind: ServiceAccount
3+
metadata:
4+
name: task
5+
---
6+
apiVersion: rbac.authorization.k8s.io/v1
7+
kind: Role
8+
metadata:
9+
name: task
10+
rules:
11+
- apiGroups:
12+
- ""
13+
- apps
14+
- batch
15+
resources:
16+
- configmaps
17+
- events
18+
- jobs
19+
- persistentvolumeclaims
20+
- pods
21+
verbs: ["*"]
22+
---
23+
apiVersion: rbac.authorization.k8s.io/v1
24+
kind: RoleBinding
25+
metadata:
26+
name: task
27+
roleRef:
28+
apiGroup: rbac.authorization.k8s.io
29+
kind: Role
30+
name: task
31+
subjects:
32+
- kind: ServiceAccount
33+
name: task

0 commit comments

Comments
 (0)