We often have a requirement to access cloud managed services like blob storage, queues, databases etc from our services. A most common use case is access S3 or GCS bucket from our services to read or write data. To enable this in Truefoundry, the process is the same as you would do in a normal Kubernetes cluster. In this example below we explain the process to read and write data to blob storage - however, the concept remains roughly the same in case you are connecting to other cloud services like SQS. The key steps are:

1. Add the cloud specific code access the service in your code

from fastapi import FastAPI, UploadFile
from fastapi.responses import StreamingResponse
import boto3
import io
app = FastAPI()

AWS_REGION = "YOUR_AWS_REGION"
S3_BUCKET_NAME = "your-s3-bucket-name"

s3 = boto3.client("s3")

@app.post("/upload/{object_name}")
async def upload_file(object_name: str, file: UploadFile):
    """Uploads a file to S3."""
    contents = await file.read()
    s3.upload_fileobj(io.BytesIO(contents), S3_BUCKET_NAME, object_name)
    return {"message": f"File uploaded to s3://{S3_BUCKET_NAME}/{object_name}"}


@app.get("/download/{object_name}")
async def download_file(object_name: str):
    """Downloads a file from S3."""
    obj = s3.get_object(Bucket=S3_BUCKET_NAME, Key=object_name)
    return StreamingResponse(
        obj["Body"].iter_chunks(chunk_size=4096),
        media_type=obj["ContentType"],
        headers={"Content-Disposition": f"attachment;filename={object_name}"},
    )

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

2. Authenticate your service to access the cloud service

We need to provide the correct credentials to our code so that it can authenticate and connect to the cloud services. The exact approach depends on the cloud provider. Here’s how you can do it for the most common cloud providers:

There are two ways to authenticate your service to access AWS services:

1. Access Key and Secret Access Key

This involves setting the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables. AWS SDKs will automatically pick these up from the environment variables and authenticate with the corresponding AWS service. The accesskey and secretaccesskey can be found in the AWS console and can be generated by your Infra team.

This approach typically involves creating IAM roles, associating them with Kubernetes service accounts, and configuring your deployments to use those service accounts. Here’s a detailed breakdown:

Key Concepts

  • Kubernetes Service Accounts (SA): These are identities for processes running inside a pod. They provide a way to authenticate your pods with other Kubernetes services and external resources.
  • IAM Roles: IAM roles are sets of permissions that define what actions an AWS entity (like a user, application, or service) can perform.
  • IAM Roles for Service Accounts (IRSA): This is the key technology that allows you to map a Kubernetes service account to an IAM role. It uses AWS’s OpenID Connect (OIDC) provider capability.

Using IRSA (IAM Role for Service Accounts), you can securely grant Kubernetes deployments access to cloud services using service accounts and IAM roles, leveraging the power of IRSA for authentication and authorization. This is recommended and well understood by the Infrastructure / Devops teams. Please reach out to them to get the IAM role and service account created.

3. Select the service account for the service

Once you’ve configured the Service Account in Kubernetes following the steps above, you can select the service account for the service in the Truefoundry UI. This can be viewed after switching on the advanced options in the service deployment form.