Kubecost allows for access to an AWS Cost and Usage Report (CUR) without any Elastic Kubernetes Service (EKS) clusters in AWS by using GCP's Workload Identity Federation. This doc will show you how to configure Workload Identity and connect it to your AWS account.
Before starting this tutorial, you need to configure a CUR in AWS that is integrated with Athena. Follow 'Step 1: Setting up a CUR' and 'Step 2: Setting up Athena' in our AWS Cloud Integration doc, then return here. Because you are not following the rest of the tutorial, you will not need to download any files from our poc-common-configurations GitHub repository linked at the start of the tutorial. The details of your Athena configuration will be used later when creating the cloud integration and secret.
You will also need access to the AWS Management Account for your organization.
These steps are written using gcloud CLI commands. If you wish to perform these steps in your console, you will need gcloud CLI.
You will also need Kubecost installed on at least one GCP cluster. You will be required to provide the name and zone of this cluster.
This should be enabled by default. If not, run this command:
gcloud beta container node-pools update default-pool --cluster=<YOUR-KUBECOST-CLUSTER> --workload-metadata-from-node=GKE_METADATA_SERVER --zone=<YOUR-CLUSTER-ZONE>
In the GCP account in which your Kubecost cluster exists, create a GCP service account to bind to the Kubecost cloud-cost container pod using Workload Identity:
gcloud iam service-accounts create kubecost-aws-cur-access --display-name "AWS cross-provider CUR access For Kubecost" --format json
Add the permissions required for Workload Identity Federation:
export PROJECT_ID=$(gcloud config get-value project)
gcloud iam service-accounts add-iam-policy-binding kubecost-aws-cur-access@$PROJECT_ID.iam.gserviceaccount.com --role roles/iam.workloadIdentityUser --member "serviceAccount:$PROJECT_ID.svc.id.goog[kubecost/kubecost-sa]"
{% hint style="info" %}
[kubecost/kubecost-sa]
can be replaced with whatever [/] as desired, if the config above is modified.
{% endhint %}
Allow the service account to generate OIDC ID tokens for authentication with AWS:
gcloud iam service-accounts add-iam-policy-binding kubecost-aws-cur-access@$PROJECT_ID.iam.gserviceaccount.com --role roles/iam.serviceAccountOpenIdTokenCreator --member "kubecost-aws-cur-access@$PROJECT_ID.iam.gserviceaccount.com"
Use the following manifest:
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
iam.gke.io/gcp-service-account: kubecost-aws-cur-access@<YOUR-PROJECT_ID>.iam.gserviceaccount.com
name: kubecost-sa
namespace: kubecost
From your AWS management account:
- Access the IAM Dashboard, then select Roles in the left navigation.
- Select Create Role.
- For 'Trusted entity type', select Web identity.
- For 'Web identity', in the 'Identity provider' dropdown, select Google.
- In the 'Audience' box, select the unique service account ID for the
kubecost-aws-cur-role
, then select Next. - Add CUR access permissions, then select Next.
- Review the details for your role for accuracy, then select Create role.
Create a cloud-integration.json
file and provide the following values (see below for explanations of these values):
{
"aws": {
"athena": [
{
"bucket": "<s3://ATHENA_RESULTS_BUCKET_NAME>",
"region": "<ATHENA_REGION>",
"database": "<ATHENA_DATABASE>",
"table": "<ATHENA_TABLE>",
"workgroup": "<ATHENA_WORKGROUP>",
"account": "<ACCOUNT_NUMBER>",
"authorizer": {
"authorizerType": "AWSWebIdentity",
"identityProvider": "Google",
"roleARN": "<PAYER_ACCOUNT_IAM_ROLE_ARN>",
"tokenRetriever": {
"aud": "<GCP_SERVICE_ACCOUNT_ID>"
}
}
}
]
}
}
{% hint style="info" %}
The aud
parameter should match the value for 'Audience' you provided in Step 4.5 (the unique service account ID for the kubecost-aws-cur-role
). roleARN
should be the ARN of the role created with that audience in Step 4.
{% endhint %}
Next, create a secret from your cloud-integration.json
:
kubectl create secret generic cloud-integration -n kubecost --from-file=cloud-integration.json
Run the following command with the appropriate service account and integration values:
helm upgrade --install kubecost --repo https://kubecost.github.io/cost-analyzer/ cost-analyzer --namespace kubecost --set serviceAccount.name=kubecost-sa --set serviceAccount.create=false --set kubecostProductConfigs.cloudIntegrationSecret=cloud-integration