Sharing AWS resources across namespaces using SSM and IRSA
This article explains how to access a resource in one Kubernetes namespace from another using IAM, IRSA and SSM:
For example, namespace-one needs to read from an S3 bucket in namespace-two
This can be done by hard-coding the resource. This guide explains how to avoid hard-coding the resource by using SSM to share the resource name and ARN.
For more information on AWS "IAM roles for Service Accounts" (IRSA), please see IAM roles for Kubernetes Service Accounts:
The Cloud Platform utilises the cloud-platform-terraform-irsa module. Please make sure you are using the latest release in the following config:
Required Configuration:
1.Add the resource name and ARN to AWS SSM in namespace-two
Here is an example of how to add an S3 bucket ARN and name as SSM parameters:
2.Create the IAM role for service accounts config
Create a file (cross-namespace-role-sa.tf) inside the namespace-one folder in the cloud-platform-environments repo,
update the template below with the correct values and raise a PR.
tags = {
business-unit = "<Which part of the MoJ is responsible for this service? (e.g HMPPS, Legal Aid Agency)>"
application = "<Application name>"
is-production = "<true/false>"
environment-name = "<dev/test/staging/prod>"
owner = "<team responsible for this application>"
infrastructure-support = "<Email address for contact/support>"
}
}
resource "kubernetes_secret" "irsa" {
metadata {
name = "irsa-output"
namespace = "<namespace>"
}
data = {
role = module.irsa.aws_iam_role_name
serviceaccount = module.irsa.service_account_name.name
}
}
]
resources = [
# refer to the ssm parameter containing the arn of the resource you want to access
"${data.aws_ssm_parameter.namespace-two-s3-bucket-arn.value}/*",
]
}
}
resource "aws_iam_policy" "<namespace>_<policy_name>" {
name = "<namespace>-<policy-name>"
policy = data.aws_iam_policy_document.<namespace>_<policy_name>.json
tags = {
business-unit = "<Which part of the MoJ is responsible for this service? (e.g HMPPS, Legal Aid Agency)>"
application = "<Application name>"
is-production = "<true/false>"
environment-name = "<dev/test/staging/prod>"
owner = "<team responsible for this application>"
infrastructure-support = "<Email address for contact/support>"
}
}
resource "kubernetes_secret" "irsa" {
metadata {
name = "irsa-output"
namespace = "<namespace>"
}
data = {
role = module.irsa.aws_iam_role_name
serviceaccount = module.irsa.service_account_name.name
}
}
# this is the ssm parameter used to supply the application with the S3 bucket name in a k8s secret
data "aws_ssm_parameter" "s3-bucket-name" {
name = "/namespace-two/s3-bucket-name"
}
# this is the ssm parameter which the aws_iam_policy_document refers to
data "aws_ssm_parameter" "s3-bucket-arn" {
name = "/namespace-two/s3-bucket-arn"
}
# this is for the application to read from the S3 bucket
resource "kubernetes_secret" "s3-bucket-secret" {
metadata {
name = "s3-bucket-secret"
namespace = var.namespace
}
data = {
# reads the S3 bucket name from an SSM parameter
bucket_name = data.aws_ssm_parameter.s3-bucket-name.value
}
}
}
-
The service account and the service account IAM role will be created with a random string in the format
cloud-platform-jhsdflisuhdfihand can be changed by passing theservice_accountvariable. Make sure there is no existing service_account in the same name. Please see the module README for optional inputs. -
Once the PR is merged, the IAM role and serviceaccount will be stored as a kubernetes_secret called
irsa-outputin your namespace.
3.Use the Serviceaccount to deploy your app
Decode the secret irsa-output to get the serviceaccount name and add it to your depolyment manifest as shown in example below:
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-rubyapp
spec:
replicas: 1
selector:
matchLabels:
app: helloworld-rubyapp
template:
metadata:
labels:
app: helloworld-rubyapp
spec:
serviceAccountName: <serviceaccount>
containers:
- name: rubyapp
image: ministryofjustice/cloud-platform-helloworld-ruby:1.1
ports:
- containerPort: 4567
Was this page useful?