Use Case

Unleashing Rapid Development with Ampt: An AI Use Case

How Antstack used Ampt to build an AI image generator application without configuring or managing complex infrastructure.

  • Sutej Bali
  • Soham Tamboli
  • Mohammed Khan

Developing feature-rich applications in the cloud often entails time-consuming infrastructure setup and maintenance, which can distract from focusing on the core application logic and user experience. While the traditional Infrastructure as Code (IaC) approach demands significant effort and expertise in managing infrastructure, Ampt introduces a novel 'Infrastructure From Code' method that significantly streamlines this process. This approach enables developers to focus exclusively on their application code, liberating them from the complexities of infrastructure. In this blog post, we dive into how Ampt simplifies cloud infrastructure management, drawing from our experience of creating an AI image generator using this innovative platform.

About Ampt

Ampt revolutionizes the way developers work by simplifying the cloud infrastructure provisioning and management process. The platform deploys your application in isolated AWS accounts, which eliminates the need for you to manage or even think about the underlying infrastructure.

Ampt is a developer tool, account orchestrator, deployment engine, and cloud management wizard—all rolled into one. It wears many hats to make your life easier, so you don't have to wear multiple hats while coding. You can use modern JavaScript and TypeScript effortlessly, connect to different services, and even bring in your favorite tools without any issues.

AI Based Image Generator App with Ampt

Our image generator application utilizes AI to generate images based on supplied prompts. It displays the generated images and enables users to bookmark them. We also designed a feature to showcase users' bookmarked images with provided prompts, offering the option to remove them from bookmarks. To facilitate user engagement, we included pre-generated images and prompts, providing a starting point for users to explore image generation within our application. We built the frontend with Next.js and the backend with Express.js, integrating various Ampt interfaces and modules. The Ampt AI module, based on Amazon Bedrock, powers the image generation.

Without Ampt, we’d need to create a frontend with HTML, CSS, and React, and host it on AWS Amplify. On the backend, a serverless approach would mandate the use of Lambda for processing requests and running application code, API Gateway to manage requests, AWS Bedrock for image generation, S3 for image storage, Parameter Store for handling secrets, Cognito for user authentication, and DynamoDB or RDS for persistent data storage. Not to mention the intricate setup and maintenance of IAM roles and policies. The complexity of this alternative would inevitably shift our primary focus from writing application code to managing and maintaining infrastructure.

With Ampt, things are much simpler. We used Ampt’s Next.js template and opted for an architecture that seamlessly integrates Node.js Express with Ampt using the HTTP interface. Ampt Storage is utilized for storing generated images, Ampt Parameters handles secret storage, Ampt Tasks manage cron jobs, the Ampt Data module persists data, and the Ampt AI module takes care of image generation. The only infrastructure we had to code and maintain was for AWS Cognito and we used the AWS SDK for this purpose. Check out the source code here and see the architecture diagram below for our application.

Antstack Ampt AI Architecture Diagram
Architecture Diagram

Ampt significantly simplified the collaboration, testing, and deployment phases of our application. It provided us with developer sandboxes, allowing us to develop and rigorously test our features in isolation before integrating them into the main production environment. This feature was particularly beneficial for ensuring the stability and reliability of our application. When we are ready to publish the changes, all we need to do is merge our code to the main branch thanks to built-in CI/CD with GitHub integration.

Diving into the details of implementation with Ampt

Although Ampt has many different interfaces, it still doesn’t have the authentication flow that users can use in the Ampt way. You will need to handle this with the tokens you can get from authentication providers like Auth0 or AWS Cognito. To manage user authentication flow, we designed and implemented an AWS Cognito resource. Leveraging the Cognito SDK, we seamlessly integrated the authentication flow into our application's middleware function. The presence of the Parameters interface proved invaluable in securely maintaining our Cognito resource API's secrets. Importing and using stored secrets became as simple as an import statement and a call to parameters with the key name of the stored parameter.

javascript
import { params } from '@ampt/sdk'; // importing params interface const cognitoIdentityServiceProvider = new CognitoIdentityProviderClient({ region: params('region'), // accessing region from params }); const verifyToken = async (token) => { const verifier = CognitoJwtVerifier.create({ userPoolId: params('userPoolId'), // accessing userPoolId from params tokenUse: 'access', clientId: params('userPoolClientId'), // accessing userPoolClientId from params }); try { const payload = await verifier.verify(token); return true; } catch { console.log('Token not valid!'); return false; } };

The core of our application centered around generating and storing images. We used Ampt's AI module (@ampt/ai), backed by Amazon Bedrock, to generate images based on user prompts. Integrating AI with Ampt was not only simple and efficient but also versatile, offering options to customize generated images.

The storage interface offered various methods for file operations, including writing, reading, checking file existence, deletion, and generating URLs. The getDownloadUrl method, in particular, provided URLs for images, simplifying the handling of image storage.

javascript
import { storage } from '@ampt/sdk'; import { data } from '@ampt/data'; import { render } from '@ampt/ai'; const imageStorage = storage('images'); // middleware controller function to handle generate image api's const generateImage = async (req, res) => { try { const prompt = req.body.prompt.replace(/(\\r\\n|\\n|\\r)/gm, ''); const response = await render(prompt); // render image // get count of images from the DB to determine next id let imageCount = await data.get('imageIdCount'); if (!imageCount) { await data.set('imageIdCount', 0); imageCount = 0; } const newImageId = await data.add('imageIdCount', 1); // get image as a buffer const imageBuffer = await response.arrayBuffer(); // store generated image in S3 await imageStorage.write(`/generatedImage/${newImageId}`, imageBuffer, { type: 'image/jpeg', }); // get saved images download url const imageUrl = await imageStorage.getDownloadUrl( `/generatedImage/${newImageId}` ); // get generated image temp store let tempImageList = await data.get('temporaryImageStore'); if (!tempImageList) { tempImageList = []; } // add imageId to tempImageList and persist to DB tempImageList.push({ imageId: newImageId, prompt: req.body.prompt }); await data.set('temporaryImageStore', tempImageList); // send image id and image url as success response res.send({ success: true, data: { id: newImageId, imageUrl: imageUrl } }); } catch (error) { console.log(error); res.status(500).send({ success: false, message: 'Internal Server Error' }); } };

The development of the application was so simple as Ampt’s interfaces and modules made most of the resources easily accessible via code. This not only saved a lot of time that we would spend on setting up the infrastructure but helped us concentrate on the application code.

Ampt as the go-to solution moving forward

It was a joyful process to use Ampt while developing the image generator app without wasting any time thinking about the infrastructure. Ampt is a game-changer for developers, providing a robust set of features and benefits that significantly simplifies the app development journey. From effortless HTTP handling to advanced AI, Ampt streamlines development, freeing you from infrastructure complexities while still keeping the infrastructure on AWS rather than some sort of black box architecture. In our upcoming webinar, we are going to deep dive into our experience building this application and compare it with the “traditional” approaches of building software with Infrastructure as Code. Don’t forget to register here.

The fastest way to get things done in the cloud!