Use Catalyst Quickstart with AWS
In this tutorial, you will select one of the API quickstart applications to try out the Catalyst APIs using AWS resources. The source code used for this tutorial can be found in the catalyst-quickstarts GitHub repository.
Select the API quickstart you would like to deploy to AWS:
- Pub/Sub
- State
- Invocation
Prerequisites
Requirement | Instructions |
---|---|
Diagrid Account | To sign up for Catalyst, visit catalyst.diagrid.io |
Diagrid CLI | Install the Diagrid CLI |
GitHub Account | Get one for free |
AWS account | For getting started on AWS, visit create and activate an AWS account |
AWS CLI | Install the AWS CLI |
Log in to AWS
To authenticate to AWS from the AWS CLI, use short-term access credentials. You can set these credentials to automatically refresh upon expiration, or you can manually configure the temp credentials using environment variables to get up and running quickly.
As an example, you can set your AWS access credentials and preferred deployment region as environment variables which are then used to configure AWS access from the CLI.
export AWS_ACCESS_KEY_ID=XXX
export AWS_SECRET_ACCESS_KEY=YYY
export AWS_DEFAULT_REGION=us-east-1
aws configure
Need more support configuring access to AWS from the AWS CLI?
- Follow the instructions here for assistance generating short-term AWS access credentials.
- See the AWS docs on setting up the AWS CLI.
Deploy infrastructure services to AWS
Select the API quickstart you plan to deploy to view the relevant instructions.
- Pub/Sub
- State
- Invocation
This tutorial will use SNS/SQS for the Pub/Sub component target. SNS topics and SQS subscriptions are provisioned on-demand by the Catalyst SNS/SQS component, therefore no manual deployment steps are required.
This tutorial will use DynamoDB for the State component target. A DynamoDB table will be created for persisting key/value pairs.
Deploy DynamoDB for State component
Create an AWS DynamoDB table which will be used as the backing store for the State API.
export DYNAMODB_TABLE_NAME="orders1"
aws dynamodb create-table --table-name $DYNAMODB_TABLE_NAME --attribute-definitions AttributeName=key,AttributeType=S --key-schema AttributeName=key,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5
No AWS infrastructure services are needed for service invocation.
Prepare Diagrid Catalyst resources
Log in
Authenticate to your Diagrid Catalyst organization using the following command:
diagrid login
Confirm your login was successful:
diagrid whoami
Create project
If you do not have an existing project available within your organization, create a new Catalyst project.
diagrid project create catalyst-project -w
To ensure this project is set as the default project in the Diagrid CLI, run:
diagrid project use catalyst-project
Retrieve the HTTP and gRPC endpoints for your Catalyst project. These endpoints will be used to make requests to Catalyst from the quickstart application.
export DAPR_HTTP_ENDPOINT=$(diagrid project get -o json | jq -r '.status.endpoints.http.url')
export DAPR_GRPC_ENDPOINT=$(diagrid project get -o json | jq -r '.status.endpoints.grpc.url')
echo $DAPR_HTTP_ENDPOINT && echo $DAPR_GRPC_ENDPOINT
Create App IDs
In Catalyst, each application is represented via a corresponding remote identity, known as an App ID
. An App ID functions as the single point of contact for all interactions between a specific application and the Catalyst APIs.
- Pub/Sub
- State
- Invocation
Create two App IDs: one for the publishing app and one for the subscribing app.
diagrid appid create publisher && diagrid appid create subscriber
Retrieve the API token for the publisher
App ID. App ID API tokens are used to authenticate API requests to Catalyst.
export PUBLISHER_API_TOKEN=$(diagrid appid get publisher -o json | jq -r '.status.apiToken')
echo $PUBLISHER_API_TOKEN
Create an App ID for the order app which is managing order state via the State API.
diagrid appid create order-app
Retrieve the API token for the order-app
App ID. App ID API tokens are used to authenticate API requests to Catalyst.
export ORDERAPP_API_TOKEN=$(diagrid appid get order-app -o json | jq -r '.status.apiToken')
echo $ORDERAPP_API_TOKEN
Create two App IDs: one for the client (invoker) app and one for the server (invokee) app.
diagrid appid create client && diagrid appid create server
Retrieve the API token for the client
App ID. App ID API tokens are used to authenticate API requests to Catalyst.
export CLIENT_API_TOKEN=$(diagrid appid get client -o json | jq -r '.status.apiToken')
echo $CLIENT_API_TOKEN
Onboard AWS infrastructure to Catalyst
- Pub/Sub
- State
- Invocation
In order to use SNS/SQS with the Pub/Sub API, you need represent that resource in Catalyst via a Pub/Sub Component. The component contains the authentication information needed by Catalyst to securely access the AWS resource.
Create AWS access keys
In order to authenticate to AWS infrastructure from a component, an identity is required which has the necessary permissions to interact with the target resource- AWS SNS/SQS. The following permissions will be attached to the IAM user:
- AmazonSNSFullAccess
- AmazonSQSFullAccess
Create a new IAM user:
aws iam create-user --user-name catalyst-pubsub
Attach the required SNS/SQS policies:
# Attach the AmazonSNSFullAccess policy
aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AmazonSNSFullAccess --user-name catalyst-pubsub
# Attach the AmazonSQSFullAccess policy
aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AmazonSQSFullAccess --user-name catalyst-pubsub
Create an access key:
aws iam create-access-key --user-name catalyst-pubsub
Copy the AccessKeyId
and the SecretAccessKey
from the response:
{
"AccessKey": {
"UserName": "catalyst-pubsub",
"AccessKeyId": <your-access-key>,
"Status": "Active",
"SecretAccessKey": <your-secret-key>,
"CreateDate": "2024-05-08T02:33:38+00:00"
}
}
Store the output as environment variables:
export COMPONENT_ACCESS_KEY=<your-access-key>
export COMPONENT_SECRET_KEY=<your-secret-key>
Create pub/sub component
Now that we have retrieved the appropriate authentication credentials, we can create the AWS infrastructure components. There are several ways to create components as described in Connect to external infrastructure. In this tutorial, we will use the non-prompt based CLI experience.
Create the AWS SNS/SQS Pub/Sub Component:
diagrid component create aws-pubsub --type pubsub.aws.snssqs --metadata accessKey=$COMPONENT_ACCESS_KEY --metadata secretKey=$COMPONENT_SECRET_KEY --metadata awsRegion=$AWS_DEFAULT_REGION --scopes publisher,subscriber
diagrid component get aws-pubsub
Create topic subscription
To configure the subscriber app to receive messages published by the publisher app through the Pub/Sub API, create a topic subscription targeting the aws-pubsub
component with the following details:
- Subscription name:
aws-subscription
- Target Pub/Sub component:
aws-pubsub
- Topic on which to listen for messages:
orders
- Default route on the subscriber app for message delivery:
/neworder
- Subscribing App IDs (scopes):
subscriber
diagrid subscription create aws-subscription --component aws-pubsub --topic orders --route /neworder --scopes subscriber
diagrid subscription get aws-subscription
In order to use DynamoDB with the State API, you need represent that resource in Catalyst via a State Component. The component contains the authentication information needed by Catalyst to securely access the AWS resource.
Create AWS access keys
In order to authenticate to AWS infrastructure from a component, an identity is required which has the necessary permissions to interact with the target resource- AWS SNS/SQS. The following permissions will be attached to the IAM user:
- AmazonDynamoDBFullAccess
Create a new IAM user:
aws iam create-user --user-name catalyst-state
Attach the required SNS/SQS policies:
# Attach the AmazonDynamoDBFullAccess policy
aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess --user-name catalyst-state
Create an access key:
aws iam create-access-key --user-name catalyst-state
Copy the AccessKeyId
and the SecretAccessKey
from the response:
{
"AccessKey": {
"UserName": "catalyst-state",
"AccessKeyId": <your-access-key>,
"Status": "Active",
"SecretAccessKey": <your-secret-key>,
"CreateDate": "2024-05-08T02:33:38+00:00"
}
}
"AccessKeyId": "AKIATD5NOTER6LB2VJ7A", "Status": "Active", "SecretAccessKey": "B/keNYMn1vXz9IxN7ANXE6eWduONJkWNCnHuD4S8",
Store the output as environment variables:
export COMPONENT_ACCESS_KEY=<your-access-key>
export COMPONENT_SECRET_KEY=<your-secret-key>
Create state component
Now that we have retrieved the appropriate authentication credentials, we can create the AWS infrastructure components. There are several ways to create components as described in Connect to external infrastructure. In this tutorial, we will use the non-prompt based CLI experience.
Create the AWS DynamoDB State Component:
diagrid component create aws-statestore --type state.aws.dynamodb --metadata accessKey=$COMPONENT_ACCESS_KEY --metadata secretKey=$COMPONENT_SECRET_KEY --metadata awsRegion=$AWS_DEFAULT_REGION --metadata table="orders" --scopes order-app
diagrid component get aws-statestore
No components need to be onboarded for service invocation.
Deploy containerized quickstart applications to AWS App Runner
This tutorial uses the quickstart apps available in the catalyst-quickstarts GitHub repository. These applications have been containerized and pushed to a public registry.
- Pub/Sub
- State
- Invocation
For the Pub/Sub quickstart, you will deploy two services:
publisher
app which makes requests to the Catalyst Publish APIsubscriber
app which subscribes to and receives the messages published by thepublisher
app through Catalyst
To make API requests to Catalyst, the publisher application uses the OSS Dapr SDKs. Environment variables will be configured to enable the Dapr Client to connect to Catalyst instead of a locally-running Dapr sidecar.
Learn more about using the Dapr SDKs to access Catalyst APIs here.
Run the below command to specify a language for the quickstart:
- Python
- .NET
- JavaScript
- Java
export LANGUAGE=python
export LANGUAGE=csharp
export LANGUAGE=javascript
export LANGUAGE=java
Deploy publisher application
Deploy the publisher application to App Runner. This command will:
- Deploy the sample application in the language of your choice to App Runner
- Configure the environment variables required for the application to invoke Catalyst API calls
- Expose the App Runner instance on a publically-accessible endpoint
aws apprunner create-service --service-name publisher \
--source-configuration '{
"ImageRepository": {
"ImageIdentifier": "public.ecr.aws/diagrid/pubsub-'${LANGUAGE}'-publisher-qs:latest",
"ImageRepositoryType": "ECR_PUBLIC",
"ImageConfiguration": { "RuntimeEnvironmentVariables": {
"DAPR_HTTP_ENDPOINT": "'${DAPR_HTTP_ENDPOINT}'",
"DAPR_API_TOKEN" : "'${PUBLISHER_API_TOKEN}'",
"DAPR_GRPC_ENDPOINT" : "'${DAPR_GRPC_ENDPOINT}'",
"PUBSUB_NAME": "aws-pubsub"
}, "Port": "5002" }},
"AutoDeploymentsEnabled": false }' \
--instance-configuration '{ "Cpu": "512", "Memory": "1024"}' \
--network-configuration '{"EgressConfiguration": { "EgressType": "DEFAULT" }, "IngressConfiguration": {"IsPubliclyAccessible": true}}'
It may take up to 5 minutes for the App Runner deployment to successfully complete.
Deploy subscriber application
Deploy the subscriber application to App Runner. This command will:
- Deploy the sample application in the language of your choice to App Runner
- Expose the App Runner instance on a publically-accessible endpoint
aws apprunner create-service --service-name subscriber \
--source-configuration '{
"ImageRepository": {
"ImageIdentifier": "public.ecr.aws/diagrid/pubsub-'${LANGUAGE}'-subscriber-qs:latest",
"ImageRepositoryType": "ECR_PUBLIC",
"ImageConfiguration": { "Port": "5002" }},
"AutoDeploymentsEnabled": false }' \
--instance-configuration '{ "Cpu": "512", "Memory": "1024"}' \
--network-configuration '{"EgressConfiguration": { "EgressType": "DEFAULT" }, "IngressConfiguration": {"IsPubliclyAccessible": true}}'
It may take up to 5 minutes for the App Runner deployment to successfully complete.
Update the subscriber App ID with an app endpoint
Retrieve the FQDN for the subscriber application and associate it with the subscriber
App ID to ensure incoming requests and events from the Catalyst APIs are sent to the running application.
export SUBSCRIBER_APP_ENDPOINT=$(aws apprunner list-services | jq -r '.ServiceSummaryList[] | select(.ServiceName=="subscriber") | .ServiceUrl')
echo $SUBSCRIBER_APP_ENDPOINT
To ensure incoming App ID requests and events can be forwarded to the subscriber application, update the subscriber
App ID with the subscriber application endpoint and wait for the operation to complete.
diagrid appid update subscriber --app-endpoint https://$SUBSCRIBER_APP_ENDPOINT -w
For the State quickstart you will deploy one service:
order-app
which makes requests to the Catalyst State API
To make API requests to Catalyst, the order-app application uses the OSS Dapr SDKs. Environment variables will be configured to enable the Dapr Client to connect to Catalyst instead of a locally-running Dapr sidecar.
Learn more about using the Dapr SDKs to access Catalyst APIs here.
Run the below command to specify a language for the quickstart:
- Python
- .NET
- JavaScript
- Java
export LANGUAGE=python
export LANGUAGE=csharp
export LANGUAGE=javascript
export LANGUAGE=java
Deploy order-app application
Deploy the order-app application to App Runner. This command will:
- Deploy the sample application in the language of your choice to App Runner
- Configure the environment variables required for the application to invoke the State API
- Expose the App Runner instance on a publically-accessible endpoint
aws apprunner create-service --service-name order-app \
--source-configuration '{
"ImageRepository": {
"ImageIdentifier": "public.ecr.aws/diagrid/state-'${LANGUAGE}'-qs:latest",
"ImageRepositoryType": "ECR_PUBLIC",
"ImageConfiguration": { "RuntimeEnvironmentVariables": {
"DAPR_HTTP_ENDPOINT": "'${DAPR_HTTP_ENDPOINT}'",
"DAPR_API_TOKEN" : "'${ORDERAPP_API_TOKEN}'",
"DAPR_GRPC_ENDPOINT" : "'${DAPR_GRPC_ENDPOINT}'",
"STATESTORE_NAME": "aws-statestore"
}, "Port": "5001" }},
"AutoDeploymentsEnabled": false }' \
--instance-configuration '{ "Cpu": "512", "Memory": "1024"}' \
--network-configuration '{"EgressConfiguration": { "EgressType": "DEFAULT" }, "IngressConfiguration": {"IsPubliclyAccessible": true}}'
It may take up to 5 minutes for the App Runner deployment to successfully complete.
For the Service Invocation quickstart, you will deploy two services:
client
app which makes requests to the Catalyst Invoke APIserver
app which receives the invocation request made by theclient
app through Catalyst
To make API requests to Catalyst, the client application uses the OSS Dapr SDKs. Environment variables will be configured to enable the Dapr Client to connect to Catalyst instead of a locally-running Dapr sidecar.
Learn more about using the Dapr SDKs to access Catalyst APIs here.
Run the below command to specify a language for the quickstart:
- Python
- .NET
- JavaScript
- Java
export LANGUAGE=python
export LANGUAGE=csharp
export LANGUAGE=javascript
export LANGUAGE=java
Deploy client application
Deploy the client application to App Runner. This command will:
- Deploy the sample application in the language of your choice to App Runner
- Configure the environment variables required for the application to invoke the Invocation API
- Expose the App Runner instance on a publically-accessible endpoint
aws apprunner create-service --service-name client \
--source-configuration '{
"ImageRepository": {
"ImageIdentifier": "public.ecr.aws/diagrid/invoke-'${LANGUAGE}'-client-qs:latest",
"ImageRepositoryType": "ECR_PUBLIC",
"ImageConfiguration": { "RuntimeEnvironmentVariables": {
"DAPR_HTTP_ENDPOINT": "'${DAPR_HTTP_ENDPOINT}'",
"DAPR_API_TOKEN" : "'${CLIENT_API_TOKEN}'",
"DAPR_GRPC_ENDPOINT" : "'${DAPR_GRPC_ENDPOINT}'",
"INVOKE_APPID": "server"
}, "Port": "5001" }},
"AutoDeploymentsEnabled": false }' \
--instance-configuration '{ "Cpu": "512", "Memory": "1024"}' \
--network-configuration '{"EgressConfiguration": { "EgressType": "DEFAULT" }, "IngressConfiguration": {"IsPubliclyAccessible": true}}'
It may take up to 5 minutes for the App Runner deployment to successfully complete.
Deploy server application
Deploy the server application to App Runner. This command will:
- Deploy the sample application in the language of your choice to App Runner
- Expose the App Runner instance on a publically-accessible endpoint
aws apprunner create-service --service-name server \
--source-configuration '{
"ImageRepository": {
"ImageIdentifier": "public.ecr.aws/diagrid/invoke-'${LANGUAGE}'-server-qs:latest",
"ImageRepositoryType": "ECR_PUBLIC",
"ImageConfiguration": { "Port": "5002" }},
"AutoDeploymentsEnabled": false }' \
--instance-configuration '{ "Cpu": "512", "Memory": "1024"}' \
--network-configuration '{"EgressConfiguration": { "EgressType": "DEFAULT" }, "IngressConfiguration": {"IsPubliclyAccessible": true}}'
It may take up to 5 minutes for the App Runner deployment to successfully complete.
Update the server App ID with an app endpoint
Retrieve the FQDN for the server application and associate it with the server
App ID to ensure incoming requests and events from the Catalyst APIs are sent to the running application.
export SERVER_APP_ENDPOINT=$(aws apprunner list-services | jq -r '.ServiceSummaryList[] | select(.ServiceName=="server") | .ServiceUrl')
echo $SERVER_APP_ENDPOINT
To ensure incoming App ID requests and events can be forwarded to the server application, update the server
App ID with the server application endpoint and wait for the operation to complete.
diagrid appid update server --app-endpoint https://$SERVER_APP_ENDPOINT -w
Interact with the Catalyst APIs
- Pub/Sub
- State
- Invocation
You've now successfully deployed the application code and all of the necessary Catalyst resources to begin invoking the Pub/Sub API.
Retrieve the App Runner URL of the publisher app which will be used to send requests.
export PUBLISHER_APP_ENDPOINT=$(aws apprunner list-services | jq -r '.ServiceSummaryList[] | select(.ServiceName=="publisher") | .ServiceUrl')
echo $PUBLISHER_APP_ENDPOINT
Use this command to kick off API calls from the publisher application which in turn uses the Catalyst Publish API.
curl -i -X POST https://$PUBLISHER_APP_ENDPOINT/order -H "Content-Type: application/json" -d '{"orderId":1}'
Check API Logs
Navigate to the Catalyst console to confirm the request was successful using the API Logs. You should see two requests:
- An inbound request from the publisher app using the publisher App ID API token to publish the order message
- An outbound request from the subscriber App ID to deliver the message to the configured AWS app endpoint
You've now successfully deployed the application code and all of the necessary Catalyst resources to begin invoking the State API.
Retrieve the App Runner URL of the order-app app which will be used to send requests.
export ORDERAPP_APP_ENDPOINT=$(aws apprunner list-services | jq -r '.ServiceSummaryList[] | select(.ServiceName=="order-app") | .ServiceUrl')
echo $ORDERAPP_APP_ENDPOINT
Use these commands to kick off API calls from the order-app application which in turn calls the Catalyst State API:
Save a key/value pair
curl -i -X POST https://$ORDERAPP_APP_ENDPOINT/order -H "Content-Type: application/json" -d '{"orderId":1}'
Update the value of orderId in the data payload with a new key to store another key/value pair.
Retrieve an existing key/value pair
curl -i -X GET https://$ORDERAPP_APP_ENDPOINT/order/1
Delete an existing key/value pair
curl -i -X DELETE https://$ORDERAPP_APP_ENDPOINT/order/1
Check API Logs
Navigate to the Catalyst console to confirm the requests were successful using the API Logs.
You've now successfully deployed the application code and all of the necessary Catalyst resources to begin invoking the Invocation API.
Retrieve the App Runner URL of the client app which will be used to send requests.
export CLIENT_APP_ENDPOINT=$(aws apprunner list-services | jq -r '.ServiceSummaryList[] | select(.ServiceName=="client") | .ServiceUrl')
echo $CLIENT_APP_ENDPOINT
Use this command to kick off API calls from the publisher application which in turn uses the Catalyst Invocation API.
curl -i -X POST https://$CLIENT_APP_ENDPOINT/order -H "Content-Type: application/json" -d '{"orderId":1}'
Check API Logs
Navigate to the Catalyst console to confirm the request was successful using the API Logs. You should see two requests:
- An inbound request from the client app using the client App ID API token
- An outbound request from the server App ID to deliver the invocation request to the configured AWS app endpoint
Clean up resources
You can use these commands to clean up the AWS and Catalyst resources you created once you are done using them.
- Pub/Sub
- State
- Invocation
Delete App Runner instances
aws apprunner delete-service --service-arn=`aws apprunner list-services | jq -r '.ServiceSummaryList[] | select(.ServiceName=="publisher") | .ServiceArn'`
aws apprunner delete-service --service-arn=`aws apprunner list-services | jq -r '.ServiceSummaryList[] | select(.ServiceName=="subscriber") | .ServiceArn'`
Delete SQS queue, SNS topic, and subscription
export TOPIC_ARN=$(aws sns list-topics --query "Topics[?ends_with(TopicArn, 'orders')].TopicArn | [0]" --output text)
export SUBSCRIPTION_ARN=$(aws sns list-subscriptions-by-topic --topic-arn=$TOPIC_ARN | jq -r '.Subscriptions[0].SubscriptionArn')
export QUEUE_URL=$(aws sqs list-queues --queue-name-prefix=subscriber | jq -r '.QueueUrls[0]')
aws sns unsubscribe --subscription-arn=$SUBSCRIPTION_ARN
aws sns delete-topic --topic-arn=$TOPIC_ARN
aws sqs delete-queue --queue-url=$QUEUE_URL
Delete Catalyst resources
diagrid appid delete publisher
diagrid appid delete subscriber
diagrid component delete aws-pubsub
If you want to delete the entire Catalyst project, including the managed infrastructure resources, run the diagrid project delete
command.
diagrid project delete catalyst-project
Delete App Runner instance
aws apprunner delete-service --service-arn=`aws apprunner list-services | jq -r '.ServiceSummaryList[] | select(.ServiceName=="order-app") | .ServiceArn'`
Delete DynamoDB table
Delete the DynamoDB orders table.
aws dynamodb delete-table --table-name=orders
Delete Catalyst resources
diagrid appid delete order-app
diagrid component delete aws-statestore
If you want to delete the entire Catalyst project, including the managed infrastructure resources, run the diagrid project delete
command.
diagrid project delete catalyst-project
Delete App Runner instance
aws apprunner delete-service --service-arn=`aws apprunner list-services | jq -r '.ServiceSummaryList[] | select(.ServiceName=="client") | .ServiceArn'`
aws apprunner delete-service --service-arn=`aws apprunner list-services | jq -r '.ServiceSummaryList[] | select(.ServiceName=="server") | .ServiceArn'`
Delete Catalyst resources
diagrid appid delete client
diagrid appid delete server
If you want to delete the entire Catalyst project, including the managed infrastructure resources, run the diagrid project delete
command.
diagrid project delete catalyst-project