Skip to content

Commit

Permalink
docs: permissions & reference roles (#443)
Browse files Browse the repository at this point in the history
Co-authored-by: Casper da Costa-Luis <casper.dcl@physics.org>
  • Loading branch information
0x2b3bfa0 and casperdcl authored Mar 17, 2022
1 parent fcc25f3 commit fff90c1
Show file tree
Hide file tree
Showing 6 changed files with 353 additions and 6 deletions.
44 changes: 38 additions & 6 deletions docs/guides/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ page_title: Authentication

# Authentication

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

```bash
$ export GOOGLE_APPLICATION_CREDENTIALS_DATA="$(cat service_account.json)"
$ terraform apply
export GOOGLE_APPLICATION_CREDENTIALS_DATA="$(cat service_account.json)"
terraform apply
```

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

See the [AWS documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html) for more information.
See the [AWS documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html) to obtain these variables directly.

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:

```bash
terraform init && terraform apply
export AWS_ACCESS_KEY_ID="$(terraform output --raw aws_access_key_id)"
export AWS_SECRET_ACCESS_KEY="$(terraform output --raw aws_secret_access_key)"
```

## Microsoft Azure

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

See the [Azure documentation](https://docs.microsoft.com/en-us/python/api/azure-identity/azure.identity.environmentcredential) for more information.
See the [Azure documentation](https://docs.microsoft.com/en-us/python/api/azure-identity/azure.identity.environmentcredential) to obtain these variables directly.

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:

```bash
terraform init && terraform apply
export AZURE_TENANT_ID="$(terraform output --raw azure_tenant_id)"
export AZURE_SUBSCRIPTION_ID="$(terraform output --raw azure_subscription_id)"
export AZURE_CLIENT_ID="$(terraform output --raw azure_client_id)"
export AZURE_CLIENT_SECRET="$(terraform output --raw azure_client_secret)"
```

## Google Cloud Platform

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

See the [GCP documentation](https://cloud.google.com/docs/authentication/getting-started#creating_a_service_account) for more information.
See the [GCP documentation](https://cloud.google.com/docs/authentication/getting-started#creating_a_service_account) to obtain these variables directly.

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:

```bash
terraform init && terraform apply
export GOOGLE_APPLICATION_CREDENTIALS_DATA="$(terraform output --raw google_application_credentials_data)"
```

## Kubernetes

Either one of:

- `KUBECONFIG` - Path to a [`kubeconfig` file](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#the-kubeconfig-environment-variable).
- `KUBECONFIG_DATA` - Alternatively, the **contents** of a `kubeconfig` file.

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:

```bash
kubectl apply --filename main.yml
export KUBECONFIG_DATA="$(bash kubeconfig.sh)"
```
81 changes: 81 additions & 0 deletions docs/guides/permissions/aws/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
terraform {
required_providers {
aws = { source = "hashicorp/aws", version = "~> 4.3.0" }
}
}

variable "aws_region" {
description = "Name of the Amazon Web Services region to use"
}

provider "aws" {
region = var.aws_region
}

resource "aws_iam_user" "task" {
name = "task"
}
resource "aws_iam_access_key" "task" {
user = aws_iam_user.task.name
}
resource "aws_iam_user_policy" "task" {
name = aws_iam_user.task.name
user = aws_iam_user.task.name
policy = data.aws_iam_policy_document.task.json
}

data "aws_iam_policy_document" "task" {
statement {
actions = [
"autoscaling:CreateAutoScalingGroup",
"autoscaling:DeleteAutoScalingGroup",
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeScalingActivities",
"autoscaling:UpdateAutoScalingGroup",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CancelSpotInstanceRequests",
"ec2:CreateKeyPair",
"ec2:CreateLaunchTemplate",
"ec2:CreateSecurityGroup",
"ec2:CreateTags",
"ec2:DeleteKeyPair",
"ec2:DeleteLaunchTemplate",
"ec2:DeleteSecurityGroup",
"ec2:DescribeAutoScalingGroups",
"ec2:DescribeImages",
"ec2:DescribeInstances",
"ec2:DescribeKeyPairs",
"ec2:DescribeLaunchTemplates",
"ec2:DescribeScalingActivities",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSpotInstanceRequests",
"ec2:DescribeSubnets",
"ec2:DescribeVpcs",
"ec2:GetLaunchTemplateData",
"ec2:ImportKeyPair",
"ec2:ModifyImageAttribute",
"ec2:ModifyLaunchTemplate",
"ec2:RequestSpotInstances",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:RunInstances",
"ec2:TerminateInstances",
"s3:CreateBucket",
"s3:DeleteBucket",
"s3:DeleteObject",
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject",
]
resources = ["*"]
}
}

output "aws_access_key_id" {
value = aws_iam_access_key.task.id
}
output "aws_secret_access_key" {
value = aws_iam_access_key.task.secret
sensitive = true
}
104 changes: 104 additions & 0 deletions docs/guides/permissions/az/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
terraform {
required_providers {
azuread = { source = "hashicorp/azuread", version = "~> 2.18.0" }
azurerm = { source = "hashicorp/azurerm", version = "~> 2.98.0" }
}
}

provider "azuread" {}
provider "azurerm" {
features {}
}

data "azuread_client_config" "current" {}
data "azurerm_subscription" "current" {}

resource "azuread_application" "task" {
display_name = "task"
owners = [data.azuread_client_config.current.object_id]
}
resource "azuread_application_password" "task" {
application_object_id = azuread_application.task.object_id
}
resource "azuread_service_principal" "task" {
application_id = azuread_application.task.application_id
app_role_assignment_required = false
owners = [data.azuread_client_config.current.object_id]
}
resource "azurerm_role_definition" "task" {
name = azuread_application.task.display_name
scope = data.azurerm_subscription.current.id
permissions {
actions = [
"Microsoft.Compute/virtualMachineScaleSets/delete",
"Microsoft.Compute/virtualMachineScaleSets/delete/action",
"Microsoft.Compute/virtualMachineScaleSets/instanceView/read",
"Microsoft.Compute/virtualMachineScaleSets/networkInterfaces/read",
"Microsoft.Compute/virtualMachineScaleSets/publicIPAddresses/read",
"Microsoft.Compute/virtualMachineScaleSets/read",
"Microsoft.Compute/virtualMachineScaleSets/scale/action",
"Microsoft.Compute/virtualMachineScaleSets/skus/read",
"Microsoft.Compute/virtualMachineScaleSets/start/action",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/delete",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/networkInterfaces/ipConfigurations/publicIPAddresses/read",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/networkInterfaces/ipConfigurations/read",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/networkInterfaces/read",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/read",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/write",
"Microsoft.Compute/virtualMachineScaleSets/vmSizes/read",
"Microsoft.Compute/virtualMachineScaleSets/write",
"Microsoft.Compute/virtualMachines/delete",
"Microsoft.Compute/virtualMachines/read",
"Microsoft.Compute/virtualMachines/write",
"Microsoft.Network/networkInterfaces/delete",
"Microsoft.Network/networkInterfaces/join/action",
"Microsoft.Network/networkInterfaces/read",
"Microsoft.Network/networkInterfaces/write",
"Microsoft.Network/networkSecurityGroups/delete",
"Microsoft.Network/networkSecurityGroups/join/action",
"Microsoft.Network/networkSecurityGroups/read",
"Microsoft.Network/networkSecurityGroups/write",
"Microsoft.Network/publicIPAddresses/delete",
"Microsoft.Network/publicIPAddresses/join/action",
"Microsoft.Network/publicIPAddresses/read",
"Microsoft.Network/publicIPAddresses/write",
"Microsoft.Network/virtualNetworks/delete",
"Microsoft.Network/virtualNetworks/read",
"Microsoft.Network/virtualNetworks/subnets/delete",
"Microsoft.Network/virtualNetworks/subnets/join/action",
"Microsoft.Network/virtualNetworks/subnets/read",
"Microsoft.Network/virtualNetworks/subnets/write",
"Microsoft.Network/virtualNetworks/write",
"Microsoft.Resources/subscriptions/resourceGroups/delete",
"Microsoft.Resources/subscriptions/resourceGroups/read",
"Microsoft.Resources/subscriptions/resourceGroups/write",
"Microsoft.Storage/storageAccounts/blobServices/containers/delete",
"Microsoft.Storage/storageAccounts/blobServices/containers/read",
"Microsoft.Storage/storageAccounts/blobServices/containers/write",
"Microsoft.Storage/storageAccounts/delete",
"Microsoft.Storage/storageAccounts/listKeys/action",
"Microsoft.Storage/storageAccounts/read",
"Microsoft.Storage/storageAccounts/write",
]
}
}
resource "azurerm_role_assignment" "task" {
name = azurerm_role_definition.task.name
principal_id = azuread_service_principal.task.object_id
role_definition_id = azurerm_role_definition.task.role_definition_resource_id
scope = data.azurerm_subscription.current.id
}

output "azure_subscription_id" {
value = basename(data.azurerm_subscription.current.id)
}
output "azure_tenant_id" {
value = data.azurerm_subscription.current.tenant_id
}
output "azure_client_id" {
value = azuread_application.task.application_id
}
output "azure_client_secret" {
value = azuread_application_password.task.value
sensitive = true
}
81 changes: 81 additions & 0 deletions docs/guides/permissions/gcp/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
terraform {
required_providers {
google = { source = "hashicorp/google", version = "~> 4.12.0" }
}
}

variable "gcp_project" {
description = "Name of the Google Cloud project to use"
}

provider "google" {
project = var.gcp_project
}

data "google_project" "current" {}

resource "google_service_account" "task" {
account_id = "task-service-account"
}
resource "google_service_account_key" "task" {
service_account_id = google_service_account.task.email
}
resource "google_project_iam_binding" "task" {
project = data.google_project.current.project_id
role = "projects/${data.google_project.current.project_id}/roles/${google_project_iam_custom_role.task.role_id}"
members = ["serviceAccount:${google_service_account.task.email}"]
}
resource "google_project_iam_custom_role" "task" {
role_id = replace("${google_service_account.task.account_id}-role", "-", "_")
title = replace("${google_service_account.task.account_id}-role", "-", "_")
permissions = [
"compute.acceleratorTypes.get",
"compute.diskTypes.get",
"compute.disks.create",
"compute.firewalls.create",
"compute.firewalls.delete",
"compute.firewalls.get",
"compute.globalOperations.get",
"compute.instanceGroupManagers.create",
"compute.instanceGroupManagers.delete",
"compute.instanceGroupManagers.get",
"compute.instanceGroupManagers.update",
"compute.instanceGroups.create",
"compute.instanceGroups.delete",
"compute.instanceGroups.get",
"compute.instanceTemplates.create",
"compute.instanceTemplates.delete",
"compute.instanceTemplates.get",
"compute.instanceTemplates.useReadOnly",
"compute.instances.create",
"compute.instances.delete",
"compute.instances.get",
"compute.instances.setMetadata",
"compute.instances.setServiceAccount",
"compute.instances.setTags",
"compute.machineTypes.get",
"compute.networks.get",
"compute.networks.updatePolicy",
"compute.subnetworks.use",
"compute.subnetworks.useExternalIp",
"compute.zoneOperations.get",
"iam.serviceAccounts.actAs",
"storage.buckets.create",
"storage.buckets.delete",
"storage.buckets.get",
"storage.multipartUploads.abort",
"storage.multipartUploads.create",
"storage.multipartUploads.list",
"storage.multipartUploads.listParts",
"storage.objects.create",
"storage.objects.delete",
"storage.objects.get",
"storage.objects.list",
"storage.objects.update",
]
}

output "google_application_credentials_data" {
value = base64decode(google_service_account_key.task.private_key)
sensitive = true
}
16 changes: 16 additions & 0 deletions docs/guides/permissions/k8s/kubeconfig.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
set -euxo pipefail
SERVER="$(kubectl config view --raw --flatten --output jsonpath='{.clusters[0].cluster.server}')"
AUTHORITY="$(kubectl config view --raw --flatten --output jsonpath='{.clusters[0].cluster.certificate-authority-data}')"
SECRET="$(kubectl get serviceaccount task --output jsonpath="{.secrets[0].name}")"
TOKEN="$(kubectl get secret "$SECRET" --output jsonpath="{.data.token}" | base64 --decode)"
export KUBECONFIG="$(mktemp)"
{
kubectl config set-cluster cluster --server="https://$SERVER"
kubectl config set clusters.cluster.certificate-authority-data "$AUTHORITY"
kubectl config set-credentials task --token="$TOKEN"
kubectl config set-context cluster --cluster=cluster --user=task
kubectl config use-context cluster
} >/dev/null
cat "$KUBECONFIG"
rm "$KUBECONFIG"
33 changes: 33 additions & 0 deletions docs/guides/permissions/k8s/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: task
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: task
rules:
- apiGroups:
- ""
- apps
- batch
resources:
- configmaps
- events
- jobs
- persistentvolumeclaims
- pods
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: task
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: task
subjects:
- kind: ServiceAccount
name: task

0 comments on commit fff90c1

Please sign in to comment.