Skip to content

Commit

Permalink
Support IAM role for nobl9 agent service account.
Browse files Browse the repository at this point in the history
Using account keys is not a good practice and requires creating IAM user
account for a service. This is changed to create IAM role and attaching it
to Kubernetes ServiceAccount.
  • Loading branch information
Andrzej Voss committed Jun 10, 2024
1 parent 1199a42 commit 91e6fa5
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 25 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ To learn how to contribute please read the [contribution guidelines](./CONTRIBUT
how about following the steps in [this tutorial](https://developer.hashicorp.com/terraform/tutorials/kubernetes/eks)?
The tutorial defaults to Terraform Cloud (which is quite nice) but for this exercise we recommend you click on the Terraform OSS
tabs as you proceed.
- You need to configure [IAM OIDC provider for the EKS cluster](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html).
Tutorial linked above does it for you, but if you are using an existing cluster, you may need to do it manually.

2. Create a `terraform.tfvars` file. A staring point can be found in `terraform.tfvars.example`

Expand Down
1 change: 1 addition & 0 deletions modules/nobl9/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module "n9agent" {
namespace = var.namespace
agent_client_id = module.data_source.client_id
agent_client_secret = module.data_source.client_secret
cluster_id = var.cluster_id
}

module "slos" {
Expand Down
10 changes: 6 additions & 4 deletions modules/nobl9/n9agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ No modules.

| Name | Type |
|------|------|
| [aws_iam_access_key.nobl9-ekg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_access_key) | resource |
| [aws_iam_user.nobl9-ekg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user) | resource |
| [aws_iam_user_policy.nobl9-ekg-ro](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user_policy) | resource |
| [aws_iam_role.nobl9-ekg-ro](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy.nobl9-ekg-ro](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [helm_release.n9agent](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource |
| [kubernetes_secret.aws_credentials](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) | resource |
| [kubernetes_service_account.service_account](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service_account) | resource |
| [aws_caller_identity.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_eks_cluster.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster) | data source |
| [aws_iam_policy_document.nobl9-ekg-ro](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |

## Inputs
Expand All @@ -40,6 +41,7 @@ No modules.
| <a name="input_agent_client_id"></a> [agent\_client\_id](#input\_agent\_client\_id) | Client ID of the data source agent (from Nobl9 UI: Integrations > Sources > [your data source] > Agent Configuration) | `string` | n/a | yes |
| <a name="input_agent_client_secret"></a> [agent\_client\_secret](#input\_agent\_client\_secret) | Client Secret of the data source agent (from Nobl9 UI: Integrations > Sources > [your data source] > Agent Configuration) | `string` | n/a | yes |
| <a name="input_chart_version"></a> [chart\_version](#input\_chart\_version) | Version of Helm Chart | `string` | `"1.0.4"` | no |
| <a name="input_cluster_id"></a> [cluster\_id](#input\_cluster\_id) | Name of the Kubernetes cluster | `string` | n/a | yes |
| <a name="input_data_source_name"></a> [data\_source\_name](#input\_data\_source\_name) | Name (ID) of the agent data source in Nobl9 | `string` | n/a | yes |
| <a name="input_namespace"></a> [namespace](#input\_namespace) | Namespace where Helm Chart will be installed | `string` | n/a | yes |
| <a name="input_nobl9_organization_id"></a> [nobl9\_organization\_id](#input\_nobl9\_organization\_id) | Nobl9 Organization ID (visible in Nobl9 web app under Settings > Account) | `string` | n/a | yes |
Expand Down
57 changes: 38 additions & 19 deletions modules/nobl9/n9agent/main.tf
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
resource "kubernetes_secret" "aws_credentials" {
metadata {
name = var.data_source_name
namespace = var.namespace
}
data "aws_caller_identity" "this" {}

data = {
aws_access_key_id = aws_iam_access_key.nobl9-ekg.id
aws_secret_access_key = aws_iam_access_key.nobl9-ekg.secret
}
data "aws_eks_cluster" "cluster" {
name = var.cluster_id
}

type = "Opaque"
locals {
k8s_oidc_provider = replace(data.aws_eks_cluster.cluster.identity[0].oidc[0].issuer, "https://", "")
}

resource "helm_release" "n9agent" {
Expand All @@ -25,6 +21,7 @@ resource "helm_release" "n9agent" {
nobl9_organization_id = var.nobl9_organization_id
client_id = var.agent_client_id
client_secret = var.agent_client_secret
service_account_name = kubernetes_service_account.service_account.metadata[0].name
})
]

Expand All @@ -36,13 +33,36 @@ resource "helm_release" "n9agent" {
cleanup_on_fail = true
}

resource "aws_iam_user" "nobl9-ekg" {
name = "nobl9-ekg"
path = "/"
resource "aws_iam_role" "nobl9-ekg-ro" {
name = "nobl9-ekg-ro-${var.cluster_id}"

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = ["sts:AssumeRoleWithWebIdentity"]
Effect = "Allow"
Principal = {
Federated = "arn:aws:iam::${data.aws_caller_identity.this.account_id}:oidc-provider/${local.k8s_oidc_provider}"
}
Condition = {
StringEquals = {
"${local.k8s_oidc_provider}:sub" = "system:serviceaccount:${var.namespace}:nobl9-agent"
}
}
}
]
})
}

resource "aws_iam_access_key" "nobl9-ekg" {
user = aws_iam_user.nobl9-ekg.name
resource "kubernetes_service_account" "service_account" {
metadata {
name = "nobl9-agent"
namespace = var.namespace
annotations = {
"eks.amazonaws.com/role-arn" = aws_iam_role.nobl9-ekg-ro.arn
}
}
}

data "aws_iam_policy_document" "nobl9-ekg-ro" {
Expand All @@ -53,8 +73,7 @@ data "aws_iam_policy_document" "nobl9-ekg-ro" {
}
}

resource "aws_iam_user_policy" "nobl9-ekg-ro" {
name = "nobl9-ekg"
user = aws_iam_user.nobl9-ekg.name
resource "aws_iam_role_policy" "nobl9-ekg-ro" {
policy = data.aws_iam_policy_document.nobl9-ekg-ro.json
}
role = aws_iam_role.nobl9-ekg-ro.id
}
4 changes: 2 additions & 2 deletions modules/nobl9/n9agent/templates/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ securityContext:

serviceAccount:
# -- Allow chart to create service account.
create: true
create: false
# -- Service account name. Generated from release name by default.
# name:
name: ${service_account_name}
# -- Additional labels for service account.
labels: {}
# -- Service account annotations.
Expand Down
5 changes: 5 additions & 0 deletions modules/nobl9/n9agent/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,8 @@ variable "agent_client_secret" {
type = string
sensitive = true
}

variable "cluster_id" {
description = "Name of the Kubernetes cluster"
type = string
}

0 comments on commit 91e6fa5

Please sign in to comment.