From 0b67dc336319195f253cfc69647f84083ddfd8e6 Mon Sep 17 00:00:00 2001 From: anuruddhal Date: Tue, 6 Oct 2026 14:57:37 +0530 Subject: [PATCH 1/7] Add WSO2 Integrator on AWS hub page with IAM access, ECS deployment, and AWS secrets and observability docs --- en/docs/aws.md | 192 +++++++++++++ en/docs/deploy-and-run/deploy-and-run.md | 2 + en/docs/deploy-and-run/secure/aws-access.md | 261 ++++++++++++++++++ .../secure/secrets-encryption.md | 70 ++++- .../self-hosted/containerized-deployment.md | 193 +++++++++++++ .../self-hosted/serverless-deployment.md | 15 + .../self-hosted/vm-deployment.md | 24 ++ en/docs/observe/logging.md | 11 + en/docs/observe/metrics.md | 4 + en/docs/observe/tracing.md | 2 + en/src/theme/DocSidebar/Desktop/icons.tsx | 10 + 11 files changed, 778 insertions(+), 6 deletions(-) create mode 100644 en/docs/aws.md create mode 100644 en/docs/deploy-and-run/secure/aws-access.md diff --git a/en/docs/aws.md b/en/docs/aws.md new file mode 100644 index 00000000000..f1b19b2422d --- /dev/null +++ b/en/docs/aws.md @@ -0,0 +1,192 @@ +--- +title: WSO2 Integrator on AWS +description: Everything WSO2 Integrator offers on Amazon Web Services, with links to the guides for AWS connectors, event triggers, IAM role-based authentication, deployment on Amazon ECS, Amazon EKS, Amazon EC2, and AWS Lambda, secrets, private networking, and observability. +keywords: [wso2 integrator, aws, amazon web services, aws connectors, sqs, sns, s3, dynamodb, iam role, amazon ecs, fargate, amazon eks, aws lambda, ec2, secrets manager, cloudwatch, x-ray] +slug: /aws +sidebar_position: 6.5 +sidebar_label: AWS +hide_table_of_contents: true +wide_layout: true +--- + +# WSO2 Integrator on AWS + +WSO2 Integrator has native support for AWS. Connect to AWS services with dedicated connectors, authenticate with IAM roles instead of access keys, and deploy to Amazon ECS, Amazon EKS, Amazon EC2, or AWS Lambda. Choose a topic below to get started. + +## Build + + + + +

Connect to AWS Services

+
    +
  • Amazon SQS, SNS, S3, DynamoDB, SES, and more
  • +
  • Amazon RDS and ElastiCache through general connectors
  • +
+
+ + +

React to AWS Events

+

Run integrations when messages and events arrive.

+
+ SQS listener + Lambda event handlers +
+
+ + +

Call Any AWS API

+
    +
  • SigV4 request signing
  • +
  • Region and FIPS endpoint resolution
  • +
+
+ +
+ +## Deploy + + + + +

Amazon ECS on Fargate

+
    +
  • Serverless containers
  • +
  • Images in Amazon ECR
  • +
+
+ + +

Amazon EKS

+
    +
  • Kubernetes manifests from Code to Cloud
  • +
  • Network Load Balancer access
  • +
+
+ + +

Amazon EC2

+
    +
  • Executable JAR on a VM
  • +
  • Instance profile credentials
  • +
+
+ + +

AWS Lambda

+
    +
  • Event-driven functions
  • +
  • S3, SQS, DynamoDB, SES, and API Gateway events
  • +
+
+ +
+ +## Secure and run + + + + +

IAM Credentials

+

Use IAM roles instead of access keys.

+
+ Default credential chain + Attach an IAM role + Cross-account access +
+
+ + +

Secrets and Configuration

+
    +
  • AWS Secrets Manager and SSM Parameter Store
  • +
  • Inject at startup or read at runtime
  • +
+
+ + +

Private Networking

+
    +
  • VPC endpoints
  • +
  • FIPS and dual-stack endpoints
  • +
+
+ + +

Observe

+

Use AWS monitoring services.

+
+ CloudWatch Logs + AWS X-Ray + Managed Prometheus +
+
+ +
+ +## AWS connectors + +Each AWS service has its own connector. Add a connector from the WSO2 Integrator connector palette, or import it in code. On AWS, configure connectors with `auth:DEFAULT_CREDENTIALS` so they use the IAM role of the compute environment. See [Access AWS Services Securely](deploy-and-run/secure/aws-access.md). + + + + +

Messaging and Notifications

+

Queue messages, publish to topics, and send email.

+ +
+ + +

Storage

+

Manage buckets and objects, including multipart uploads and presigned URLs.

+
+ Amazon S3 +
+
+ + +

Databases and Analytics

+

Read and write NoSQL data, follow table changes, and query data warehouses.

+ +
+ + +

Security

+

Read secrets at runtime.

+ +
+ + +

AWS Marketplace

+

Meter usage and check entitlements for Marketplace products.

+ +
+ + +

General-Purpose Connectors

+

Use the engine's database connector for Amazon RDS and Aurora, and the Redis connector for ElastiCache and MemoryDB.

+ +
+ +
+ +For AI integrations, [`ballerinax/ai.aws.dynamodb`](https://central.ballerina.io/ballerinax/ai.aws.dynamodb/latest) stores agent conversation memory in DynamoDB. For change data capture, [`ballerinax/cdc.schema.aws.s3.driver`](https://central.ballerina.io/ballerinax/cdc.schema.aws.s3.driver/latest) keeps the [CDC connector](pathname:///integration-platform/docs/connectors/catalog/database/cdc/connector-overview)'s schema history in S3. To browse every connector, see the [connector catalog](pathname:///integration-platform/docs/connectors/catalog). diff --git a/en/docs/deploy-and-run/deploy-and-run.md b/en/docs/deploy-and-run/deploy-and-run.md index aaa667083de..1596fa231fa 100644 --- a/en/docs/deploy-and-run/deploy-and-run.md +++ b/en/docs/deploy-and-run/deploy-and-run.md @@ -36,6 +36,7 @@ Choose where your integrations run. Where you deploy also decides how you [manag Virtual machines Serverless GraalVM native images + AWS @@ -87,6 +88,7 @@ Choose where your integrations run. Where you deploy also decides how you [manag API security Secrets and encryption Compliance + AWS access diff --git a/en/docs/deploy-and-run/secure/aws-access.md b/en/docs/deploy-and-run/secure/aws-access.md new file mode 100644 index 00000000000..98d24fee6f8 --- /dev/null +++ b/en/docs/deploy-and-run/secure/aws-access.md @@ -0,0 +1,261 @@ +--- +title: Access AWS Services Securely +description: Give WSO2 Integrator AWS credentials through IAM roles on Amazon ECS, Amazon EKS, Amazon EC2, and AWS Lambda, assume roles across accounts, sign requests to any AWS API, and keep AWS traffic inside your VPC. +keywords: [wso2 integrator, aws, iam role, default credentials, assume role, irsa, eks pod identity, instance profile, sigv4, vpc endpoints, fips] +slug: /deploy-and-run/secure/aws-access +sidebar_position: 9 +--- + +# Access AWS Services Securely + +All AWS connectors share one authentication model from the [`ballerinax/aws.auth`](https://central.ballerina.io/ballerinax/aws/latest) module, so a credential setup that works for one connector works for all of them. This page covers how to give an integration AWS credentials without storing access keys, how to reach resources in other accounts, how to call AWS APIs that don't have a connector, and how to keep AWS traffic private. + +The credential setting is the `auth` field of the connector configuration, except in `aws.dynamodbstreams`, where it is named `credentials`. + +:::note +The `aws.redshift` connector authenticates with a database user and password over JDBC, and `ai.aws.dynamodb` takes access keys. Neither uses this model. +::: + +## Use the default credential chain + +When the integration runs on AWS, set `auth` to `auth:DEFAULT_CREDENTIALS`. The connector then uses temporary credentials from the IAM role attached to the compute environment and refreshes them before they expire. There are no access keys to store, rotate, or leak. + +```ballerina +import ballerinax/aws; +import ballerinax/aws.auth; +import ballerinax/aws.sqs; + +final sqs:Client sqsClient = check new ({ + region: aws:US_EAST_1, + auth: auth:DEFAULT_CREDENTIALS +}); +``` + +The default chain checks the following sources in order and uses the first one that returns credentials: + +1. JVM system properties +2. Environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN`) +3. Web identity token (EKS IRSA) +4. IAM Identity Center (SSO) session +5. Shared config and credentials files (`~/.aws/config`, `~/.aws/credentials`) +6. External credential process +7. Container credentials (ECS task role, EKS Pod Identity) +8. EC2 instance profile (IMDS) + +Because the chain also reads `~/.aws/credentials` and SSO sessions, the same code runs unchanged on your workstation after `aws configure` or `aws sso login`. + +:::tip +Make sure no `AWS_ACCESS_KEY_ID` or `AWS_SECRET_ACCESS_KEY` environment variables are set in your container image or task definition. Environment variables come earlier in the chain than the IAM role, so stray keys silently take precedence over the role. +::: + +## Attach an IAM role + +Grant the role only the actions your integration calls. For example, an integration that consumes one queue needs this policy: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "sqs:ReceiveMessage", + "sqs:DeleteMessage", + "sqs:GetQueueAttributes" + ], + "Resource": "arn:aws:sqs:us-east-1::orders" + } + ] +} +``` + +Then attach the role in the way your compute service expects. + +### Amazon ECS + +Set the role as the **task role** (`taskRoleArn`) in the task definition. The ECS agent serves its credentials to the container, and the default chain reads them as container credentials. See [Amazon ECS deployment](../self-hosted/containerized-deployment.md#amazon-ecs-deployment). + +:::note +ECS uses two roles. The **task role** is what your integration code runs as. The **task execution role** is what the ECS agent uses to pull the image, write logs, and fetch secrets for injection. Put connector permissions on the task role only. +::: + +### Amazon EKS + +EKS offers two ways to bind an IAM role to a pod. Both work with `DEFAULT_CREDENTIALS` without code changes. + +**EKS Pod Identity** (recommended for new clusters). Install the `eks-pod-identity-agent` add-on, then associate the role with a Kubernetes service account: + +```bash +aws eks create-pod-identity-association \ + --cluster-name \ + --namespace \ + --service-account my-integration \ + --role-arn arn:aws:iam:::role/my-integration-role +``` + +The role's trust policy must allow the `pods.eks.amazonaws.com` service principal to call `sts:AssumeRole` and `sts:TagSession`. + +**IAM Roles for Service Accounts (IRSA)**. Associate an OIDC provider with the cluster, create a role that trusts it, and annotate the service account with the role ARN: + +```yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: my-integration + namespace: + annotations: + eks.amazonaws.com/role-arn: arn:aws:iam:::role/my-integration-role +``` + +EKS injects `AWS_ROLE_ARN` and `AWS_WEB_IDENTITY_TOKEN_FILE` into every pod that uses this service account, and the default chain picks them up. + +With either option, the pod must run as that service account. The manifests generated by `bal build` use the namespace's `default` service account, so set the service account after deploying: + +```bash +kubectl create serviceaccount my-integration # skip if you applied the IRSA manifest above +kubectl patch deployment my-integration-deployment \ + -p '{"spec":{"template":{"spec":{"serviceAccountName":"my-integration"}}}}' +``` + +To keep this change across rebuilds, apply it as a [Kustomize](https://kustomize.io/) patch on the generated manifests. + +### Amazon EC2 + +Attach an **instance profile** that contains the role. See [Run on Amazon EC2](../self-hosted/vm-deployment.md#run-on-amazon-ec2). + +### AWS Lambda + +Lambda runs the function as its **execution role**. See [Grant AWS permissions to a Lambda function](../self-hosted/serverless-deployment.md#grant-aws-permissions). + +## Access resources in another AWS account + +To reach a resource in another account, have the connector assume a role in that account by passing an `auth:AssumeRoleConfig`: + +```ballerina +final sqs:Client partnerQueue = check new ({ + region: aws:EU_WEST_1, + auth: { + roleArn: "arn:aws:iam:::role/order-queue-writer", + roleSessionName: "wso2-integrator", + stsRegion: aws:EU_WEST_1 + } +}); +``` + +The connector first resolves its own identity through `sourceCredentials`, which defaults to `auth:DEFAULT_CREDENTIALS`. It then calls STS `AssumeRole` and renews the session before it expires. The session lasts `duration` seconds, 3600 by default. For this to work: + +- The role in the other account must trust the role your integration runs as. +- The role your integration runs as must be allowed to call `sts:AssumeRole` on the target role. +- If the other account requires an external ID, set `externalId`. + +:::tip +`stsRegion` defaults to `us-east-1`. Set it to the region your integration runs in, so STS calls stay in that region and can use an STS VPC endpoint. +::: + +## Other credential sources + +The `auth` field also accepts the following configurations. They are mainly useful outside AWS, or when you want to pin one source instead of relying on the chain. + +| Configuration | Use when | +|---------------|----------| +| `auth:StaticAuthConfig` (`accessKeyId`, `secretAccessKey`, optional `sessionToken`) | Quick local tests, or systems that cannot use roles. Avoid in production. | +| `auth:ProfileAuthConfig` (`profileName`, `credentialsFilePath`) | Local development with a named profile from `aws configure` | +| `auth:SsoAuthConfig` (`ssoStartUrl`, `ssoRegion`, `accountId`, `roleName`) | Local development with IAM Identity Center after `aws sso login` | +| `auth:WebIdentityConfig` (`roleArn`, `webIdentityTokenFile`) | CI/CD pipelines and other platforms that issue OIDC tokens | +| `auth:ProcessAuthConfig` (`command`) | Workloads outside AWS that use IAM Roles Anywhere or another `credential_process` helper | + +## Call AWS APIs without a connector + +For AWS services without a dedicated connector, use `ballerinax/aws` and `ballerinax/aws.auth` with a plain `http:Client`. `aws:resolveEndpointHost` finds the service endpoint for a region, and `auth:getSignedHeaders` signs the request with AWS Signature Version 4, using the same credential sources as the connectors. + +The following example publishes an event to Amazon EventBridge: + +```ballerina +import ballerina/http; +import ballerinax/aws; +import ballerinax/aws.auth; + +final auth:CredentialProvider credentials = check new (auth:DEFAULT_CREDENTIALS); +final string eventsHost = aws:resolveEndpointHost("events", aws:US_EAST_1); +final http:Client eventBridge = check new ("https://" + eventsHost); + +public function publishOrderPlaced(string orderId) returns error? { + json body = { + Entries: [ + { + Source: "com.example.orders", + DetailType: "OrderPlaced", + Detail: {orderId}.toJsonString() + } + ] + }; + byte[] payload = body.toJsonString().toBytes(); + + map signedHeaders = check auth:getSignedHeaders({ + method: "POST", + host: eventsHost, + headers: { + "content-type": "application/x-amz-json-1.1", + "x-amz-target": "AWSEvents.PutEvents" + }, + payload + }, check credentials.getCredentials(), aws:US_EAST_1, "events"); + + http:Request request = new; + request.setBinaryPayload(payload); + foreach [string, string] [name, value] in signedHeaders.entries() { + request.setHeader(name, value); + } + http:Response response = check eventBridge->execute("POST", "/", request); +} +``` + +Create one `auth:CredentialProvider` and reuse it. It caches credentials and renews temporary credentials automatically. + +## Keep AWS traffic inside your VPC + +To let tasks and pods in private subnets reach AWS services without a NAT gateway, add VPC endpoints for the services your deployment and connectors use: + +| Service | Endpoint service name | Type | Needed for | +|---------|----------------------|------|------------| +| ECR API | `com.amazonaws..ecr.api` | Interface | Image pulls | +| ECR Docker | `com.amazonaws..ecr.dkr` | Interface | Image pulls | +| S3 | `com.amazonaws..s3` | Gateway | Image layers and the `aws.s3` connector | +| CloudWatch Logs | `com.amazonaws..logs` | Interface | The `awslogs` log driver | +| Secrets Manager | `com.amazonaws..secretsmanager` | Interface | Secret injection and the `aws.secretmanager` connector | +| SSM | `com.amazonaws..ssm` | Interface | Parameter injection | +| STS | `com.amazonaws..sts` | Interface | IRSA, web identity, and assume-role credentials | +| SQS, SNS, and others | `com.amazonaws..sqs`, `com.amazonaws..sns`, and so on | Interface | The matching connectors | +| DynamoDB | `com.amazonaws..dynamodb` | Gateway | The `aws.dynamodb` connector | + +When an interface endpoint has **private DNS** enabled, the service's regular hostname resolves to the endpoint inside the VPC, so the connectors need no changes. To use a different endpoint, set the connector's `endpoint` field: + +| Setting | Effect | +|---------|--------| +| `endpoint: {fips: true}` | Uses FIPS 140 validated endpoints, for example for FedRAMP workloads in AWS GovCloud (US) | +| `endpoint: {dualstack: true}` | Uses endpoints that support both IPv4 and IPv6 | +| `endpoint: {customEndpoint: ""}` | Calls the given URL, such as an endpoint-specific VPC endpoint DNS name or [LocalStack](https://www.localstack.cloud/) during local testing | + +```ballerina +final sqs:Client sqsClient = check new ({ + region: aws:US_GOV_WEST_1, + auth: auth:DEFAULT_CREDENTIALS, + endpoint: {fips: true} +}); +``` + +## Troubleshooting + +| Symptom | Likely cause | Fix | +|---------|--------------|-----| +| `auth:CredentialResolutionError` at startup | No source in the default chain returned credentials | Check that a role is attached: the task role on ECS, a service account association on EKS, or an instance profile on EC2. | +| `AccessDenied` that names an unexpected principal | Access keys in environment variables take precedence over the role | Remove `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` from the image and from the task or pod spec. | +| `AccessDenied` on `sts:AssumeRole` | The trust policy or the caller's permission is missing | The target role must trust the caller's role, and the caller needs `sts:AssumeRole` on the target role. | +| A pod on EKS uses the node's role instead of its own | The pod runs as the `default` service account | Set `serviceAccountName` on the deployment and restart the pods. | +| A container on EC2 cannot get credentials | The IMDSv2 hop limit is `1` | Set `--http-put-response-hop-limit 2` on the instance. | + +## What's next + +- [WSO2 Integrator on AWS](../../aws.md): everything WSO2 Integrator offers on AWS +- [Secrets and Encryption](secrets-encryption.md#aws-secrets-manager): load configuration from AWS Secrets Manager and SSM Parameter Store +- [Containerized Deployment](../self-hosted/containerized-deployment.md#amazon-ecs-deployment): deploy to Amazon ECS on Fargate or Amazon EKS diff --git a/en/docs/deploy-and-run/secure/secrets-encryption.md b/en/docs/deploy-and-run/secure/secrets-encryption.md index 50f97d1a1b4..95eeb791267 100644 --- a/en/docs/deploy-and-run/secure/secrets-encryption.md +++ b/en/docs/deploy-and-run/secure/secrets-encryption.md @@ -216,18 +216,74 @@ function readInjectedSecret(string filePath) returns map|error { ## AWS Secrets Manager +On AWS, keep secrets in AWS Secrets Manager (or as `SecureString` parameters in SSM Parameter Store) and let the integration read them in one of two ways. + +### Inject secrets at startup + +Have the platform resolve each secret and pass it to the integration as a `BAL_CONFIG_VAR_` environment variable. The integration code only declares a `configurable` variable and never calls AWS: + ```ballerina -import ballerinax/aws.secretsmanager; +configurable string dbPassword = ?; +``` + +- **Amazon ECS**: list the secrets in the `secrets` block of the task definition. ECS fetches them with the task execution role when the task starts. See [Amazon ECS deployment](../self-hosted/containerized-deployment.md#step-5-register-the-task-definition). +- **Amazon EKS**: use the [External Secrets Operator](https://external-secrets.io/) to sync secrets into a Kubernetes Secret. Install the operator and create a `ClusterSecretStore` for AWS by following the [operator's AWS guide](https://external-secrets.io/latest/provider/aws-secrets-manager/), then define the values to sync: + + ```yaml + apiVersion: external-secrets.io/v1 + kind: ExternalSecret + metadata: + name: my-integration-config + spec: + refreshInterval: 1h + secretStoreRef: + name: aws-secretsmanager + kind: ClusterSecretStore + target: + name: my-integration-env + data: + - secretKey: BAL_CONFIG_VAR_DBPASSWORD + remoteRef: + key: prod/my-integration/db + property: password + ``` + + Load the synced Secret into the integration's container: + + ```bash + kubectl set env deployment/my-integration-deployment --from=secret/my-integration-env + ``` -secretsmanager:Client smClient = check new ({ - region: "us-east-1", - accessKeyId: accessKeyId, - secretAccessKey: secretAccessKey + To keep this change across rebuilds, apply it as a [Kustomize](https://kustomize.io/) patch on the generated manifests. + +Environment variables are read only when the process starts. After you rotate a secret, restart the integration to pick up the new value: run `aws ecs update-service --force-new-deployment` on ECS, or `kubectl rollout restart` on EKS. + +### Read secrets at runtime + +To pick up rotated values without a restart, read the secret with the [`ballerinax/aws.secretmanager`](pathname:///integration-platform/docs/connectors/catalog/security-identity/aws.secretmanager/aws-secrets-manager-connector-overview) connector. With `auth:DEFAULT_CREDENTIALS`, the connector uses the IAM role of the compute environment, so no access keys are needed to fetch the secret. See [Access AWS Services Securely](aws-access.md). + +```ballerina +import ballerinax/aws; +import ballerinax/aws.auth; +import ballerinax/aws.secretmanager; + +final secretmanager:Client secrets = check new ({ + region: aws:US_EAST_1, + auth: auth:DEFAULT_CREDENTIALS }); -string dbPassword = check smClient->getSecretValue("prod/db/password"); +function getDbPassword() returns string|error { + secretmanager:SecretValue secret = check secrets->getSecretValue("prod/my-integration/db"); + byte[]|string value = secret.value; + string secretString = value is string ? value : check string:fromBytes(value); + // The secret stores a JSON document such as {"password":"..."} + json document = check secretString.fromJsonString(); + return (check document.password).toString(); +} ``` +The role needs `secretsmanager:GetSecretValue` on the secret, and `kms:Decrypt` if the secret is encrypted with a customer managed KMS key. + ## TLS configuration For a detailed guide on creating keystores and truststores, see [Keystores and truststores](keystore-truststore.md). @@ -295,3 +351,5 @@ For database encryption, configure at the database level: - [Authentication](authentication.md) — Secure service endpoints with OAuth 2.0, JWT, and mTLS - [Compliance considerations](compliance-considerations.md) — Audit logging and data protection - [Runtime security](runtime-security.md) — Additional runtime security settings +- [Access AWS Services Securely](aws-access.md) — IAM role-based credentials for AWS connectors +- [WSO2 Integrator on AWS](../../aws.md) — Everything WSO2 Integrator offers on AWS diff --git a/en/docs/deploy-and-run/self-hosted/containerized-deployment.md b/en/docs/deploy-and-run/self-hosted/containerized-deployment.md index f05253d290d..0235f1e1a90 100644 --- a/en/docs/deploy-and-run/self-hosted/containerized-deployment.md +++ b/en/docs/deploy-and-run/self-hosted/containerized-deployment.md @@ -18,6 +18,7 @@ The Code to Cloud feature supports the following containerized deployment platfo - **[Kubernetes](#kubernetes-deployment)** — Deploy to any Kubernetes cluster with auto-generated manifests, services, and autoscaling configurations - **[Red Hat OpenShift](#red-hat-openshift-deployment)** — Deploy to OpenShift using the `oc` CLI with platform-specific manifests - **[Amazon EKS](#amazon-eks-deployment)** — Deploy to AWS Elastic Kubernetes Service using ECR for image hosting and an internal NLB for service access +- **[Amazon ECS](#amazon-ecs-deployment)** — Run on AWS Fargate without a Kubernetes cluster, using ECR for image hosting, IAM task roles for AWS credentials, and Secrets Manager for configuration - **[Azure AKS](#azure-aks-deployment)** — Deploy to Azure Kubernetes Service using ACR for image hosting and an Azure Load Balancer for service access :::info Prerequisites @@ -659,6 +660,10 @@ kubectl get services kubectl logs -f deployment/my-integration-deployment ``` +:::tip +To give the pods AWS credentials for connectors such as Amazon SQS or Amazon S3, bind an IAM role to the deployment's service account with EKS Pod Identity or IRSA. See [Access AWS Services Securely](../secure/aws-access.md#amazon-eks). +::: + ### Step 7: Expose and test Tag the cluster subnets so the EKS load balancer controller can discover them: @@ -720,6 +725,188 @@ curl http://.elb..amazonaws.com:9090/ An internal NLB is only reachable from within the same VPC. For internet-facing access, replace `internal-elb` with `elb` in the subnet tag and set `aws-load-balancer-scheme` to `internet-facing` in the Service manifest. Ensure the subnets have a route to an internet gateway. ::: +## Amazon ECS deployment + +Amazon Elastic Container Service (ECS) on AWS Fargate runs the container image built by Code to Cloud without a Kubernetes cluster or servers to manage. The task gets AWS credentials from its IAM task role, reads secrets from AWS Secrets Manager and SSM Parameter Store at startup, and sends its logs to Amazon CloudWatch Logs. + +### Prerequisites + +In addition to the [general prerequisites](#supported-platforms), you need: + +- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) installed and configured (`aws configure` or `aws sso login`) +- A VPC with at least two subnets, and a security group that allows inbound traffic on the integration's port (`9090` in this example) +- An [Amazon ECR](https://aws.amazon.com/ecr/) repository: + +```bash +aws ecr create-repository --region --repository-name my-integration +``` + +### Step 1: Build the image + +Set the cloud target in `Ballerina.toml`: + +```toml +[build-options] +cloud = "docker" +``` + +Point the image at your ECR repository in `Cloud.toml`: + +```toml +[container.image] +repository = ".dkr.ecr..amazonaws.com" +name = "my-integration" +tag = "v1.0.0" +``` + +Build the project: + +```bash +bal build +``` + +### Step 2: Push the image to ECR + +Log in to ECR and push the image. Fargate runs `linux/amd64` by default. On Apple Silicon or another Arm machine, build for that platform with `docker buildx`: + +```bash +aws ecr get-login-password --region | \ + docker login --username AWS --password-stdin .dkr.ecr..amazonaws.com + +docker buildx build \ + --platform linux/amd64 \ + --tag .dkr.ecr..amazonaws.com/my-integration:v1.0.0 \ + --push \ + target/docker/my_integration/ +``` + +:::tip +To run on AWS Graviton, build with `--platform linux/arm64` and add `"runtimePlatform": {"cpuArchitecture": "ARM64", "operatingSystemFamily": "LINUX"}` to the task definition. +::: + +### Step 3: Store configuration in AWS + +Keep secrets in Secrets Manager and plain settings in SSM Parameter Store: + +```bash +aws secretsmanager create-secret --region \ + --name prod/my-integration/db \ + --secret-string '{"password":""}' + +aws ssm put-parameter --region \ + --name /my-integration/prod/queue-url \ + --type String \ + --value https://sqs..amazonaws.com//orders +``` + +### Step 4: Create the IAM roles + +Create two roles that the `ecs-tasks.amazonaws.com` service principal can assume: + +- **Task execution role** (`my-integration-execution-role`): attach the AWS managed policy `AmazonECSTaskExecutionRolePolicy` for image pulls and logging. To let ECS inject the values from Step 3, add `secretsmanager:GetSecretValue` on the secret and `ssm:GetParameters` on the parameter. If the secret is encrypted with a customer managed KMS key, also add `kms:Decrypt` on that key. +- **Task role** (`my-integration-task-role`): attach the permissions your AWS connectors need. Connectors configured with `auth:DEFAULT_CREDENTIALS` pick up this role automatically. See [Access AWS Services Securely](../secure/aws-access.md#amazon-ecs). + +### Step 5: Register the task definition + +Create a log group for the container output: + +```bash +aws logs create-log-group --region --log-group-name /ecs/my-integration +``` + +Save the following as `task-definition.json`. The `secrets` block injects each value as a `BAL_CONFIG_VAR_` environment variable, which WSO2 Integrator reads into the matching `configurable` variable. The variable name after the prefix must be uppercase. See [Managing Configurations](../managing-configurations.md#environment-variable-overrides) for the naming rules. + +```json +{ + "family": "my-integration", + "requiresCompatibilities": ["FARGATE"], + "networkMode": "awsvpc", + "cpu": "1024", + "memory": "2048", + "executionRoleArn": "arn:aws:iam:::role/my-integration-execution-role", + "taskRoleArn": "arn:aws:iam:::role/my-integration-task-role", + "containerDefinitions": [ + { + "name": "my-integration", + "image": ".dkr.ecr..amazonaws.com/my-integration:v1.0.0", + "essential": true, + "portMappings": [{ "containerPort": 9090, "protocol": "tcp" }], + "secrets": [ + { + "name": "BAL_CONFIG_VAR_DBPASSWORD", + "valueFrom": "arn:aws:secretsmanager:::secret:prod/my-integration/db-:password::" + }, + { + "name": "BAL_CONFIG_VAR_QUEUEURL", + "valueFrom": "arn:aws:ssm:::parameter/my-integration/prod/queue-url" + } + ], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-group": "/ecs/my-integration", + "awslogs-region": "", + "awslogs-stream-prefix": "integration" + } + } + } + ] +} +``` + +These two entries supply these variables in your code: + +```ballerina +configurable string dbPassword = ?; +configurable string queueUrl = ?; +``` + +Register the task definition: + +```bash +aws ecs register-task-definition --region \ + --cli-input-json file://task-definition.json +``` + +### Step 6: Create the cluster and service + +```bash +aws ecs create-cluster --region --cluster-name integrations + +aws ecs create-service --region \ + --cluster integrations \ + --service-name my-integration \ + --task-definition my-integration \ + --desired-count 2 \ + --launch-type FARGATE \ + --network-configuration "awsvpcConfiguration={subnets=[,],securityGroups=[],assignPublicIp=DISABLED}" +``` + +The subnets need a route to ECR, CloudWatch Logs, and Secrets Manager. Use private subnets with either a NAT gateway or [VPC endpoints](../secure/aws-access.md#keep-aws-traffic-inside-your-vpc). + +To expose an HTTP service, put an Application Load Balancer in front of it. Add `--load-balancers targetGroupArn=,containerName=my-integration,containerPort=9090` to `create-service`. The target group must use the `ip` target type. + +### Step 7: Verify + +Check that the tasks are running: + +```bash +aws ecs describe-services --region \ + --cluster integrations --services my-integration \ + --query 'services[0].{desired:desiredCount,running:runningCount,events:events[:3]}' +``` + +Follow the integration logs: + +```bash +aws logs tail /ecs/my-integration --region --follow +``` + +If a task stops right after it starts, `aws ecs describe-tasks` shows the `stoppedReason`. The usual causes are: + +- `ResourceInitializationError`: the task execution role cannot read a secret, or the subnets have no route to Secrets Manager. Add `secretsmanager:GetSecretValue` (and `kms:Decrypt`) to the execution role, and add a NAT gateway or a VPC endpoint. +- A required `configurable` variable with no value: check the `secrets` entries and their uppercase `BAL_CONFIG_VAR_` names. + ## Azure AKS deployment Azure Kubernetes Service (AKS) follows the same Kubernetes deployment path described above, with a few Azure-specific steps: pushing the image to Azure Container Registry (ACR), attaching the registry to the cluster, and exposing the service via an Azure Load Balancer. @@ -905,3 +1092,9 @@ metadata: service.beta.kubernetes.io/azure-load-balancer-internal: "true" ``` ::: + +## What's next + +- [Managing Configurations](../managing-configurations.md) — Supply configuration values to containers +- [Scaling and High Availability](../scaling-high-availability.md) — Run multiple replicas reliably +- [WSO2 Integrator on AWS](../../aws.md) — Everything WSO2 Integrator offers on AWS diff --git a/en/docs/deploy-and-run/self-hosted/serverless-deployment.md b/en/docs/deploy-and-run/self-hosted/serverless-deployment.md index 05a56287e1c..f1f22f98cb1 100644 --- a/en/docs/deploy-and-run/self-hosted/serverless-deployment.md +++ b/en/docs/deploy-and-run/self-hosted/serverless-deployment.md @@ -164,6 +164,16 @@ public function processDynamoDB(lambda:Context ctx, } ``` +Typed event records are available for these event sources. For any other source, accept the event as `json`. + +| Event source | Event type | +|--------------|------------| +| Amazon S3 | `lambda:S3Event` | +| Amazon SQS | `lambda:SQSEvent` | +| Amazon DynamoDB Streams | `lambda:DynamoDBEvent` | +| Amazon SES | `lambda:SESEvent` | +| Amazon API Gateway (proxy integration) | `lambda:APIGatewayProxyRequest` | + ### Step 2: Build ```bash @@ -231,6 +241,10 @@ aws lambda update-function-code \ Refer to the [AWS Lambda documentation](https://docs.aws.amazon.com/lambda/) for deployment configuration and trigger setup. +### Grant AWS permissions + +Lambda runs the function as its **execution role**, the role you pass with `--role` to `aws lambda create-function`. If the function uses AWS connectors, such as Amazon S3 or Amazon DynamoDB, add the permissions they need to that role and configure the connectors with `auth:DEFAULT_CREDENTIALS`. The Lambda runtime exposes the role's credentials as environment variables, which the default credential chain reads, so the function needs no access keys. See [Access AWS Services Securely](../secure/aws-access.md). + ## Reducing cold start times ### Use GraalVM native images @@ -259,3 +273,4 @@ The compiler auto-detects the serverless platform and generates the appropriate - [GraalVM Native Images](graalvm-native-images.md) — Compile to native binaries for minimal cold start - [Managing Configurations](../managing-configurations.md) — Environment-specific configuration strategies - [Containerized Deployment](containerized-deployment.md) — Deploy as containers to Kubernetes or Docker +- [WSO2 Integrator on AWS](../../aws.md) — Everything WSO2 Integrator offers on AWS diff --git a/en/docs/deploy-and-run/self-hosted/vm-deployment.md b/en/docs/deploy-and-run/self-hosted/vm-deployment.md index 39bd1aa472f..6909274dcea 100644 --- a/en/docs/deploy-and-run/self-hosted/vm-deployment.md +++ b/en/docs/deploy-and-run/self-hosted/vm-deployment.md @@ -268,9 +268,33 @@ service /health on new http:Listener(9091) { } ``` +## Run on Amazon EC2 + +If the integration uses AWS connectors, don't copy access keys to the instance. Attach an **instance profile** that contains an IAM role with the permissions the connectors need, and configure the connectors with `auth:DEFAULT_CREDENTIALS`: + +```bash +aws ec2 associate-iam-instance-profile \ + --instance-id \ + --iam-instance-profile Name=my-integration-profile +``` + +The connectors then read temporary credentials from the instance metadata service and refresh them automatically. See [Access AWS Services Securely](../secure/aws-access.md). + +:::note +If the integration runs in a container on the instance and IMDSv2 is enforced, set the metadata hop limit to `2`. Otherwise the container cannot reach the metadata service: + +```bash +aws ec2 modify-instance-metadata-options \ + --instance-id \ + --http-put-response-hop-limit 2 \ + --http-tokens required +``` +::: + ## What's next - [Containerized Deployment](containerized-deployment.md) — Deploy your project to Docker, Kubernetes, or Red Hat OpenShift using Code to Cloud - [Managing Configurations](../managing-configurations.md) — Per-environment configuration strategies - [Scaling & High Availability](../scaling-high-availability.md) — Run multiple instances behind a load balancer - [GraalVM Native Images](graalvm-native-images.md) — Compile to native binaries for faster startup +- [WSO2 Integrator on AWS](../../aws.md) — Everything WSO2 Integrator offers on AWS diff --git a/en/docs/observe/logging.md b/en/docs/observe/logging.md index 9473b8e438b..183d4e5c222 100644 --- a/en/docs/observe/logging.md +++ b/en/docs/observe/logging.md @@ -161,8 +161,19 @@ JSON output: } ``` +## Send logs to Amazon CloudWatch Logs + +Integrations log to stdout, so on AWS the platform ships the output to CloudWatch Logs without code changes. Set `format = "json"` under `[ballerina.log]` so each log line arrives as one structured event that you can query with CloudWatch Logs Insights. + +| Platform | How logs reach CloudWatch Logs | +|----------|--------------------------------| +| Amazon ECS | The `awslogs` log driver in the task definition. See [Amazon ECS deployment](../deploy-and-run/self-hosted/containerized-deployment.md#step-5-register-the-task-definition). | +| Amazon EKS | Fluent Bit, or the Amazon CloudWatch Observability EKS add-on | +| AWS Lambda | Automatic; function output goes to the `/aws/lambda/` log group | + ## What's next - [Metrics](metrics.md) — Monitor service health with Prometheus - [Distributed tracing](tracing.md) — Trace requests across services - [Integration Control Plane](../icp/index.md) — Centralized monitoring dashboard +- [WSO2 Integrator on AWS](../aws.md) — Everything WSO2 Integrator offers on AWS diff --git a/en/docs/observe/metrics.md b/en/docs/observe/metrics.md index 8534d658aa2..30a85b00e53 100644 --- a/en/docs/observe/metrics.md +++ b/en/docs/observe/metrics.md @@ -231,6 +231,10 @@ service /orders on new http:Listener(9090) { } ``` +## Send metrics to Amazon Managed Service for Prometheus + +On AWS, have an [AWS Distro for OpenTelemetry](https://aws-otel.github.io/) collector or the CloudWatch agent scrape the integration's metrics endpoint (port `9797`), and remote-write the metrics to Amazon Managed Service for Prometheus or publish them to CloudWatch. Use the same scrape settings as in [Setting up Prometheus](#setting-up-prometheus). + ## What's next - [Prometheus and Grafana](open-source/prometheus-grafana.md) — Scrape configuration, Kubernetes, and Grafana dashboards diff --git a/en/docs/observe/tracing.md b/en/docs/observe/tracing.md index c2cedcfc2d5..137609f9d1c 100644 --- a/en/docs/observe/tracing.md +++ b/en/docs/observe/tracing.md @@ -67,6 +67,8 @@ Sampling every request is fine for development. In production, use `probabilisti | **Jaeger** | Production-grade distributed tracing | [Jaeger](open-source/jaeger.md) | | **Zipkin** | A lightweight tracing alternative | [Zipkin](open-source/zipkin.md) | +To send traces to **AWS X-Ray**, use the Jaeger extension, which exports spans over OTLP gRPC. Set `agentHostname` and `agentPort` to an [AWS Distro for OpenTelemetry](https://aws-otel.github.io/) (ADOT) collector, and configure the collector's `awsxray` exporter. Run the collector as a sidecar on Amazon ECS or as a DaemonSet on Amazon EKS. + You can also send traces to a managed platform: [Datadog](commercial/datadog.md) and [New Relic](commercial/new-relic.md) both accept traces, and [Moesif](commercial/moesif.md) supports traces alongside metrics and logs. For a complete stack that includes tracing, see the [Local Development Stack](recipes/local-development-stack.md) and [Kubernetes Production Stack](recipes/kubernetes-production-stack.md) recipes. ## What's next diff --git a/en/src/theme/DocSidebar/Desktop/icons.tsx b/en/src/theme/DocSidebar/Desktop/icons.tsx index 332ef773b66..ffef59c705e 100644 --- a/en/src/theme/DocSidebar/Desktop/icons.tsx +++ b/en/src/theme/DocSidebar/Desktop/icons.tsx @@ -299,6 +299,15 @@ function ToolsIcon(): ReactNode { ); } +function AwsIcon(): ReactNode { + return ( + + + + + ); +} + function FallbackIcon(): ReactNode { return ( @@ -328,6 +337,7 @@ const ICONS_BY_LABEL: Record ReactNode> = { 'deploy and run': DeployIcon, observe: ObserveIcon, manage: ManageIcon, + aws: AwsIcon, migrate: MigrateIcon, 'integration control plane': IntegrationControlPlaneIcon, 'integration control plane (icp)': IntegrationControlPlaneIcon, From 2815f81f31955f85ab83cbe52734c22927ade37f Mon Sep 17 00:00:00 2001 From: anuruddhal Date: Tue, 6 Oct 2026 15:14:54 +0530 Subject: [PATCH 2/7] Check HTTP status and FailedEntryCount in the EventBridge PutEvents example --- en/docs/deploy-and-run/secure/aws-access.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/en/docs/deploy-and-run/secure/aws-access.md b/en/docs/deploy-and-run/secure/aws-access.md index 98d24fee6f8..da907ad506b 100644 --- a/en/docs/deploy-and-run/secure/aws-access.md +++ b/en/docs/deploy-and-run/secure/aws-access.md @@ -207,9 +207,21 @@ public function publishOrderPlaced(string orderId) returns error? { request.setHeader(name, value); } http:Response response = check eventBridge->execute("POST", "/", request); + if response.statusCode != http:STATUS_OK { + return error(string `PutEvents failed with HTTP ${response.statusCode}: ${check response.getTextPayload()}`); + } + + // PutEvents returns HTTP 200 even when it rejects some entries + json result = check response.getJsonPayload(); + int failedEntryCount = check (check result.FailedEntryCount).ensureType(); + if failedEntryCount > 0 { + return error(string `PutEvents rejected ${failedEntryCount} entries: ${(check result.Entries).toJsonString()}`); + } } ``` +`PutEvents` can accept some entries and reject others in the same call, so check `FailedEntryCount` as well as the HTTP status. Each rejected entry in `Entries` carries an `ErrorCode` and `ErrorMessage`. + Create one `auth:CredentialProvider` and reuse it. It caches credentials and renews temporary credentials automatically. ## Keep AWS traffic inside your VPC From 44ea05bdeb271aaa0dec1bf0e032348dbd356876 Mon Sep 17 00:00:00 2001 From: anuruddhal Date: Tue, 6 Oct 2026 15:33:25 +0530 Subject: [PATCH 3/7] Point EKS, ECS, and AKS prerequisite links at a real general prerequisites anchor --- .../self-hosted/containerized-deployment.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/en/docs/deploy-and-run/self-hosted/containerized-deployment.md b/en/docs/deploy-and-run/self-hosted/containerized-deployment.md index 0235f1e1a90..3aa8c0b5556 100644 --- a/en/docs/deploy-and-run/self-hosted/containerized-deployment.md +++ b/en/docs/deploy-and-run/self-hosted/containerized-deployment.md @@ -21,12 +21,12 @@ The Code to Cloud feature supports the following containerized deployment platfo - **[Amazon ECS](#amazon-ecs-deployment)** — Run on AWS Fargate without a Kubernetes cluster, using ECR for image hosting, IAM task roles for AWS credentials, and Secrets Manager for configuration - **[Azure AKS](#azure-aks-deployment)** — Deploy to Azure Kubernetes Service using ACR for image hosting and an Azure Load Balancer for service access -:::info Prerequisites +## Prerequisites {#general-prerequisites} + - [Docker](https://www.docker.com/) installed and running on your build machine - A WSO2 Integrator project based on Ballerina - For Kubernetes: [kubectl](https://kubernetes.io/docs/tasks/tools/) installed and configured against a Kubernetes cluster - For OpenShift: [OpenShift CLI (`oc`)](https://docs.openshift.com/container-platform/latest/cli_reference/openshift_cli/getting-started-cli.html) installed and logged in to your cluster -::: :::note Package naming constraint The `name` field in `Ballerina.toml` must contain only alphanumerics, underscores, and periods — hyphens are not allowed. Use `my_integration` rather than `my-integration`. Image names in `Cloud.toml` under `[container.image]` can include hyphens. @@ -523,7 +523,7 @@ Amazon Elastic Kubernetes Service (EKS) follows the same Kubernetes deployment p ### Prerequisites -In addition to the [general prerequisites](#prerequisites), you need: +In addition to the [general prerequisites](#general-prerequisites), you need: - [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) installed and configured (`aws configure` or `aws sso login`) - An EKS cluster with `kubectl` configured: `aws eks update-kubeconfig --region --name ` @@ -731,7 +731,7 @@ Amazon Elastic Container Service (ECS) on AWS Fargate runs the container image b ### Prerequisites -In addition to the [general prerequisites](#supported-platforms), you need: +In addition to the [general prerequisites](#general-prerequisites), you need: - [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) installed and configured (`aws configure` or `aws sso login`) - A VPC with at least two subnets, and a security group that allows inbound traffic on the integration's port (`9090` in this example) @@ -913,7 +913,7 @@ Azure Kubernetes Service (AKS) follows the same Kubernetes deployment path descr ### Prerequisites -In addition to the [general prerequisites](#prerequisites), you need: +In addition to the [general prerequisites](#general-prerequisites), you need: - [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) installed and configured (`az login`) - An AKS cluster with `kubectl` configured: `az aks get-credentials --resource-group --name ` From 4146313ad7700b0364f6b7d4072412a43dee20fc Mon Sep 17 00:00:00 2001 From: anuruddhal Date: Tue, 6 Oct 2026 17:19:50 +0530 Subject: [PATCH 4/7] Read the ECS example database secret from a file instead of passing it on the command line --- .../self-hosted/containerized-deployment.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/en/docs/deploy-and-run/self-hosted/containerized-deployment.md b/en/docs/deploy-and-run/self-hosted/containerized-deployment.md index 3aa8c0b5556..ad531fad9e1 100644 --- a/en/docs/deploy-and-run/self-hosted/containerized-deployment.md +++ b/en/docs/deploy-and-run/self-hosted/containerized-deployment.md @@ -786,12 +786,18 @@ To run on AWS Graviton, build with `--platform linux/arm64` and add `"runtimePla ### Step 3: Store configuration in AWS -Keep secrets in Secrets Manager and plain settings in SSM Parameter Store: +Keep secrets in Secrets Manager and plain settings in SSM Parameter Store. + +To keep the password out of your shell history and the process list, put the secret in a file instead of on the command line. Create `db-secret.json` with a text editor, with the content `{"password":""}`, and then run: ```bash +chmod 600 db-secret.json + aws secretsmanager create-secret --region \ --name prod/my-integration/db \ - --secret-string '{"password":""}' + --secret-string file://db-secret.json + +rm db-secret.json aws ssm put-parameter --region \ --name /my-integration/prod/queue-url \ From 6f58b9c44940df1f5f278027b2caff8c990e0432 Mon Sep 17 00:00:00 2001 From: anuruddhal Date: Thu, 8 Oct 2026 10:08:39 +0530 Subject: [PATCH 5/7] Warn that a raised IMDS hop limit exposes instance profile credentials to every container on the EC2 instance --- en/docs/deploy-and-run/self-hosted/vm-deployment.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/en/docs/deploy-and-run/self-hosted/vm-deployment.md b/en/docs/deploy-and-run/self-hosted/vm-deployment.md index 6909274dcea..93e6ba38d2c 100644 --- a/en/docs/deploy-and-run/self-hosted/vm-deployment.md +++ b/en/docs/deploy-and-run/self-hosted/vm-deployment.md @@ -291,6 +291,10 @@ aws ec2 modify-instance-metadata-options \ ``` ::: +:::warning +The instance profile is shared by everything on the instance. With the hop limit at `2`, any container that can reach the metadata service, not just the integration, can get the role's credentials. Run the integration on an instance dedicated to it. If other containers must share the instance, run them on Amazon ECS with a separate task role for each, and block their access to the metadata service. For strict isolation, use AWS Fargate. See the [Amazon EC2 instance configuration for ECS task roles](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html#task-iam-role-considerations) in the AWS documentation. +::: + ## What's next - [Containerized Deployment](containerized-deployment.md) — Deploy your project to Docker, Kubernetes, or Red Hat OpenShift using Code to Cloud From 6eec53ef27c8c334ecd6fe0cb197392621cb992d Mon Sep 17 00:00:00 2001 From: anuruddhal Date: Thu, 8 Oct 2026 11:53:33 +0530 Subject: [PATCH 6/7] Use plain anchors for connector links so Docusaurus does not prefix them with the integrator base URL --- en/docs/aws.md | 2 +- en/docs/deploy-and-run/secure/secrets-encryption.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/en/docs/aws.md b/en/docs/aws.md index f1b19b2422d..0bc7774de7b 100644 --- a/en/docs/aws.md +++ b/en/docs/aws.md @@ -189,4 +189,4 @@ Each AWS service has its own connector. Add a connector from the WSO2 Integrator -For AI integrations, [`ballerinax/ai.aws.dynamodb`](https://central.ballerina.io/ballerinax/ai.aws.dynamodb/latest) stores agent conversation memory in DynamoDB. For change data capture, [`ballerinax/cdc.schema.aws.s3.driver`](https://central.ballerina.io/ballerinax/cdc.schema.aws.s3.driver/latest) keeps the [CDC connector](pathname:///integration-platform/docs/connectors/catalog/database/cdc/connector-overview)'s schema history in S3. To browse every connector, see the [connector catalog](pathname:///integration-platform/docs/connectors/catalog). +For AI integrations, [`ballerinax/ai.aws.dynamodb`](https://central.ballerina.io/ballerinax/ai.aws.dynamodb/latest) stores agent conversation memory in DynamoDB. For change data capture, [`ballerinax/cdc.schema.aws.s3.driver`](https://central.ballerina.io/ballerinax/cdc.schema.aws.s3.driver/latest) keeps the CDC connector's schema history in S3. To browse every connector, see the connector catalog. diff --git a/en/docs/deploy-and-run/secure/secrets-encryption.md b/en/docs/deploy-and-run/secure/secrets-encryption.md index 95eeb791267..3a6abb3392b 100644 --- a/en/docs/deploy-and-run/secure/secrets-encryption.md +++ b/en/docs/deploy-and-run/secure/secrets-encryption.md @@ -260,7 +260,7 @@ Environment variables are read only when the process starts. After you rotate a ### Read secrets at runtime -To pick up rotated values without a restart, read the secret with the [`ballerinax/aws.secretmanager`](pathname:///integration-platform/docs/connectors/catalog/security-identity/aws.secretmanager/aws-secrets-manager-connector-overview) connector. With `auth:DEFAULT_CREDENTIALS`, the connector uses the IAM role of the compute environment, so no access keys are needed to fetch the secret. See [Access AWS Services Securely](aws-access.md). +To pick up rotated values without a restart, read the secret with the ballerinax/aws.secretmanager connector. With `auth:DEFAULT_CREDENTIALS`, the connector uses the IAM role of the compute environment, so no access keys are needed to fetch the secret. See [Access AWS Services Securely](aws-access.md). ```ballerina import ballerinax/aws; From 31377bee721309fac66503f0d5a6144597ee235d Mon Sep 17 00:00:00 2001 From: anuruddhal Date: Thu, 8 Oct 2026 11:58:52 +0530 Subject: [PATCH 7/7] Add an AI section to the AWS page linking DynamoDB agent memory, Copilot on Bedrock, and AI-assisted migration --- en/docs/aws.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/en/docs/aws.md b/en/docs/aws.md index 0bc7774de7b..5efda8a1854 100644 --- a/en/docs/aws.md +++ b/en/docs/aws.md @@ -44,6 +44,38 @@ WSO2 Integrator has native support for AWS. Connect to AWS services with dedicat +## AI + + + + +

Agent Memory in DynamoDB

+
    +
  • Persist AI agent conversation history in Amazon DynamoDB
  • +
  • Suits serverless, AWS-native deployments
  • +
+
+ + +

Copilot with Amazon Bedrock

+

Run WSO2 Integrator Copilot on Claude models in your own Amazon Bedrock account.

+
+ Sign in with Bedrock + How Copilot uses Bedrock +
+
+ + +

AI-Assisted Migration

+

Use Amazon Bedrock for the AI enhancement step of the migration tools.

+
+ From MuleSoft + From TIBCO +
+
+ +
+ ## Deploy @@ -189,4 +221,4 @@ Each AWS service has its own connector. Add a connector from the WSO2 Integrator -For AI integrations, [`ballerinax/ai.aws.dynamodb`](https://central.ballerina.io/ballerinax/ai.aws.dynamodb/latest) stores agent conversation memory in DynamoDB. For change data capture, [`ballerinax/cdc.schema.aws.s3.driver`](https://central.ballerina.io/ballerinax/cdc.schema.aws.s3.driver/latest) keeps the CDC connector's schema history in S3. To browse every connector, see the connector catalog. +For change data capture, [`ballerinax/cdc.schema.aws.s3.driver`](https://central.ballerina.io/ballerinax/cdc.schema.aws.s3.driver/latest) keeps the CDC connector's schema history in S3. To browse every connector, see the connector catalog.