Skip to content

Commit

Permalink
add aws_gke_oidc modules
Browse files Browse the repository at this point in the history
  • Loading branch information
amitchell-moz committed Dec 18, 2024
1 parent a65cd8c commit 0c9d965
Show file tree
Hide file tree
Showing 18 changed files with 460 additions and 0 deletions.
12 changes: 12 additions & 0 deletions aws_gke_oidc_config/.terraform-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
content: |-
{{ .Header }}
## Example
```hcl
{{ include "examples/main.tf" }}
```
{{ .Inputs }}
{{ .Outputs }}
6 changes: 6 additions & 0 deletions aws_gke_oidc_config/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## 0.1.0
* PR [#239](https://github.com/mozilla/terraform-modules/pull/239) - feat: add aws_gke_oidc_config and aws_gke_oidc_role modules
```
add aws_gke_oidc_config and aws_gke_oidc_role modules
```

36 changes: 36 additions & 0 deletions aws_gke_oidc_config/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!-- BEGIN_TF_DOCS -->
# AWS-GKE OIDC Config
This module will create an AWS OIDC config that creates a trust relationship between a GKE cluster & AWS account.

Once this module has been invoked for a given account + GKE cluster, the `aws_gke_oidc_role` module can be used
to create any number of roles to be used by GKE workloads.

See the `aws_gke_oidc_role` for complete usage instructions

## Example

```hcl
/*
* Creates an OIDC trust relationship between the global-platform-admin-mgmt cluster & the authenticated AWS account.
*/
module "oidc_config" {
source = "../."
gcp_region = "us-west1"
gcp_project_id = "moz-fx-platform-mgmt-global"
gke_cluster_name = "global-platform-admin-mgmt"
}
```

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_gcp_project_id"></a> [gcp\_project\_id](#input\_gcp\_project\_id) | ID of the GKE cluster's project | `string` | n/a | yes |
| <a name="input_gcp_region"></a> [gcp\_region](#input\_gcp\_region) | GKE cluster's GCP region | `string` | n/a | yes |
| <a name="input_gke_cluster_name"></a> [gke\_cluster\_name](#input\_gke\_cluster\_name) | GKE cluster name | `string` | n/a | yes |

## Outputs

No outputs.
<!-- END_TF_DOCS -->
10 changes: 10 additions & 0 deletions aws_gke_oidc_config/examples/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Creates an OIDC trust relationship between the global-platform-admin-mgmt cluster & the authenticated AWS account.
*/

module "oidc_config" {
source = "../."
gcp_region = "us-west1"
gcp_project_id = "moz-fx-platform-mgmt-global"
gke_cluster_name = "global-platform-admin-mgmt"
}
25 changes: 25 additions & 0 deletions aws_gke_oidc_config/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* # AWS-GKE OIDC Config
* This module will create an AWS OIDC config that creates a trust relationship between a GKE cluster & AWS account.
*
* Once this module has been invoked for a given account + GKE cluster, the `aws_gke_oidc_role` module can be used
* to create any number of roles to be used by GKE workloads.
*
* See the `aws_gke_oidc_role` for complete usage instructions
*/

resource "aws_iam_openid_connect_provider" "gke_oidc" {
url = "https://container.googleapis.com/v1/projects/${var.gcp_project_id}/locations/${var.gcp_region}/clusters/${var.gke_cluster_name}"

client_id_list = [
"sts.amazonaws.com"
]

thumbprint_list = [
data.tls_certificate.gke_oidc.certificates.0.sha1_fingerprint
]
}

data "tls_certificate" "gke_oidc" {
url = "https://container.googleapis.com/v1/projects/${var.gcp_project_id}/locations/${var.gcp_region}/clusters/${var.gke_cluster_name}"
}
16 changes: 16 additions & 0 deletions aws_gke_oidc_config/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
### Required

variable "gcp_region" {
description = "GKE cluster's GCP region"
type = string
}

variable "gcp_project_id" {
description = "ID of the GKE cluster's project"
type = string
}

variable "gke_cluster_name" {
description = "GKE cluster name"
type = string
}
9 changes: 9 additions & 0 deletions aws_gke_oidc_config/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.37"
}
}
required_version = "~> 1.0"
}
16 changes: 16 additions & 0 deletions aws_gke_oidc_role/.terraform-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
content: |-
{{ .Header }}
## Example
```hcl
{{ include "examples/role_and_config/main.tf" }}
```
```hcl
{{ include "examples/role_with_policy/main.tf" }}
```
{{ .Inputs }}
{{ .Outputs }}
6 changes: 6 additions & 0 deletions aws_gke_oidc_role/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## 0.1.0
* PR [#239](https://github.com/mozilla/terraform-modules/pull/239) - feat: add aws_gke_oidc_config and aws_gke_oidc_role modules
```
add aws_gke_oidc_config and aws_gke_oidc_role modules
```

128 changes: 128 additions & 0 deletions aws_gke_oidc_role/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<!-- BEGIN_TF_DOCS -->
# AWS-GKE OIDC Role
This module will create an AWS role that will allow a specified GKE service account to assume it.

Requires that `../aws_gke_oidc_config` has been applied for a given AWS account + GKE cluster combination
if you get an error about the `aws_iam_openid_connect_provider` data source being missing, apply that module.

After creating these resources, add the following environment variables, volumes, and volume mounts to your pod definition:
* env:
```
- name: AWS_REGION
value: <YOUR_AWS_REGION_HERE>
- name: AWS_ROLE_ARN
value: <ROLE_ARN FROM OUTPUT HERE>
- name: AWS_WEB_IDENTITY_TOKEN_FILE
value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
- name: AWS_STS_REGIONAL_ENDPOINTS
value: regional
```
* volumes:
```
- name: aws-token
projected:
defaultMode: 420
sources:
- serviceAccountToken:
audience: sts.amazonaws.com
expirationSeconds: 86400
path: token
```
* volumeMounts:
```
- mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount/
name: aws-token
```

## Example

```hcl
/*
* Example of creating both an OIDC config & role to utilize it
*/
module "oidc_config" {
source = "../../../aws_gke_oidc_config/"
gcp_region = "us-west1"
gcp_project_id = "moz-fx-platform-mgmt-global"
gke_cluster_name = "global-platform-admin-mgmt"
}
module "oidc_role" {
depends_on = [module.oidc_config]
source = "../.././"
role_name = "opst-1509-oidc-test"
aws_region = "us-west-1"
gcp_region = "us-west1"
gke_cluster_name = "global-platform-admin-mgmt"
gcp_project_id = "moz-fx-platform-mgmt-global"
gke_namespace = "atlantis-sandbox"
gke_service_account = "atlantis-sandbox"
iam_policy_arns = []
}
```

```hcl
/*
* Example of creating just the role. The module will infer the OIDC url from vars.
* Attaches an inline ec2 policy & managed AWS ViewOnly policy.
* Resulting role will be assumable by the "foo" service account in the "bar" namespace of the "baz" cluster
*/
module "oidc_role" {
source = "../.././"
role_name = "oidc-example-role"
aws_region = "us-west-1"
gcp_region = "us-west1"
gke_cluster_name = "baz"
gcp_project_id = "example-project"
gke_namespace = "bar"
gke_service_account = "foo"
iam_policy_arns = [aws_iam_policy.example_policy.arn, data.aws_iam_policy.view_only.arn]
}
resource "aws_iam_policy" "example_policy" {
name = "example_policy"
path = "/"
description = "My example policy"
# Terraform's "jsonencode" function converts a
# Terraform expression result to valid JSON syntax.
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ec2:Describe*",
]
Effect = "Allow"
Resource = "*"
},
]
})
}
data "aws_iam_policy" "view_only" {
arn = "arn:aws:iam::aws:policy/job-function/ViewOnlyAccess"
}
```

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_aws_region"></a> [aws\_region](#input\_aws\_region) | AWS region | `string` | n/a | yes |
| <a name="input_gcp_project_id"></a> [gcp\_project\_id](#input\_gcp\_project\_id) | GKE cluster's project ID | `string` | n/a | yes |
| <a name="input_gcp_region"></a> [gcp\_region](#input\_gcp\_region) | GKE cluster's GCP region | `string` | n/a | yes |
| <a name="input_gke_cluster_name"></a> [gke\_cluster\_name](#input\_gke\_cluster\_name) | GKE cluster name | `string` | n/a | yes |
| <a name="input_gke_namespace"></a> [gke\_namespace](#input\_gke\_namespace) | Namespace for GKE workload | `string` | n/a | yes |
| <a name="input_gke_service_account"></a> [gke\_service\_account](#input\_gke\_service\_account) | GKE service account to grant role assumption privilleges | `string` | n/a | yes |
| <a name="input_iam_policy_arns"></a> [iam\_policy\_arns](#input\_iam\_policy\_arns) | One or more policy arns to attach to created AWS role | `list(string)` | n/a | yes |
| <a name="input_role_name"></a> [role\_name](#input\_role\_name) | Name to give the AWS role | `string` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_role_arn"></a> [role\_arn](#output\_role\_arn) | ARN for the GKE-AWS connector role |
<!-- END_TF_DOCS -->
23 changes: 23 additions & 0 deletions aws_gke_oidc_role/examples/role_and_config/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Example of creating both an OIDC config & role to utilize it
*/

module "oidc_config" {
source = "../../../aws_gke_oidc_config/"
gcp_region = "us-west1"
gcp_project_id = "moz-fx-platform-mgmt-global"
gke_cluster_name = "global-platform-admin-mgmt"
}

module "oidc_role" {
depends_on = [module.oidc_config]
source = "../.././"
role_name = "opst-1509-oidc-test"
aws_region = "us-west-1"
gcp_region = "us-west1"
gke_cluster_name = "global-platform-admin-mgmt"
gcp_project_id = "moz-fx-platform-mgmt-global"
gke_namespace = "atlantis-sandbox"
gke_service_account = "atlantis-sandbox"
iam_policy_arns = []
}
13 changes: 13 additions & 0 deletions aws_gke_oidc_role/examples/role_and_config/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

# Configure the AWS Provider
provider "aws" {
region = "us-west-2"
}
42 changes: 42 additions & 0 deletions aws_gke_oidc_role/examples/role_with_policy/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Example of creating just the role. The module will infer the OIDC url from vars.
* Attaches an inline ec2 policy & managed AWS ViewOnly policy.
* Resulting role will be assumable by the "foo" service account in the "bar" namespace of the "baz" cluster
*/

module "oidc_role" {
source = "../.././"
role_name = "oidc-example-role"
aws_region = "us-west-1"
gcp_region = "us-west1"
gke_cluster_name = "baz"
gcp_project_id = "example-project"
gke_namespace = "bar"
gke_service_account = "foo"
iam_policy_arns = [aws_iam_policy.example_policy.arn, data.aws_iam_policy.view_only.arn]
}

resource "aws_iam_policy" "example_policy" {
name = "example_policy"
path = "/"
description = "My example policy"

# Terraform's "jsonencode" function converts a
# Terraform expression result to valid JSON syntax.
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ec2:Describe*",
]
Effect = "Allow"
Resource = "*"
},
]
})
}

data "aws_iam_policy" "view_only" {
arn = "arn:aws:iam::aws:policy/job-function/ViewOnlyAccess"
}
13 changes: 13 additions & 0 deletions aws_gke_oidc_role/examples/role_with_policy/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

# Configure the AWS Provider
provider "aws" {
region = "us-west-2"
}
Loading

0 comments on commit 0c9d965

Please sign in to comment.