Building a Serverless AI-Powered Language Learning Game with AWS
Discover how I combined serverless architecture and AI-driven AWS services to build the Language Game—an interactive language-learning app for young children who cannot yet read or write. This blog covers the inspiration, architecture, challenges, and lessons learned during the journey, highlighting the pivotal role of AWS tools like Amazon Translate, Polly, SAM, and Amazon Q in streamlining development and deployment.
Published Jan 7, 2025
Last Modified Jan 9, 2025
Learn how to build a cloud-native language game using AWS services like Lambda, DynamoDB, Translate, and Polly.January 6, 2025
As a developer passionate about Cloud Native and Serverless architectures, I have always sought opportunities to experiment with cutting-edge technologies. After recently passing the AWS Developer Associate Certification, I decided to put my knowledge into action. I also found inspiration closer to home: my five-year-old son, who loves language-learning games. However, most apps in this space rely heavily on reading and writing, which he can't yet.
To bridge this gap, I developed the Language Game—a cloud-native, serverless application powered by AWS services like Amazon Translate and Amazon Polly. This app helps young children learn new languages interactively through images and AI-generated voice content.
In this blog, I’ll walk you through the journey of building this application, the AWS services I used, the challenges I faced, and the lessons I learned
Building the Language Game wasn’t without its challenges:
- Adapting to Serverless Development: While I had theoretical knowledge from my certification, applying it to real-world use cases required learning the nuances of AWS services.
- Cost Optimization: Striking the right balance between functionality and cost-efficiency required careful resource management.
Amazon Q, a developer assistant available through VS Code and the AWS web console, played an instrumental role throughout the project. Its features made the development process smoother and more efficient:
- In VS Code:
- Inline code suggestions for Python, JavaScript, and SAM templates.
- A chat window that provided architecture recommendations, SAM template guidance, and best practices.
- In the AWS Console:
- Step-by-step guidance for resource configuration.
- Recommendations to optimize service usage and security configurations.
Amazon Q saved countless hours by providing context-aware solutions, allowing me to focus on innovation rather than troubleshooting.
Developing the Language Game reinforced several important lessons:
- Serverless is Powerful: AWS services like Lambda, Translate, and Polly can handle complex workloads with ease, enabling rapid development of scalable applications.
- Automation Simplifies Deployment: Using AWS SAM made managing infrastructure-as-code straightforward and repeatable.
- Collaboration with AI Tools: Amazon Q proved invaluable as a virtual team member, offering insights and solutions at every step of the process.
In this game, players choose a language and a category, like fruits or animals, and are presented with a spoken word (audio) in the foreign language along with four images. One image corresponds to the spoken word. Players must match the correct image to the spoken word. With each correct answer, players earn points. This game is targeted at small children as it does not require reading or writing skills.
Before you begin, make sure you have the following:
- AWS CLI configured with appropriate credentials
- AWS SAM CLI installed
- Python 3.8+ (for backend development)
- AWS Account with appropriate permissions
The application consists of:
- Frontend: A static website hosted on Amazon S3 and distributed globally via CloudFront.
- Backend: Serverless functions using AWS Lambda connected to Amazon DynamoDB.
- Language Features:
- Amazon Translate for multilingual translations
- Amazon Polly for AI-powered audio
- The user visits the static website delivered by CloudFront, which fetches the
index.html
file from the S3 bucket along with other static assets. - JavaScript in the frontend calls the API resource
/language-game
, which returns the audio file as well as correct and incorrect images to display. - The backend API integrates with a Lambda function that pulls data from a DynamoDB table and generates the response.
The game has two main elements:
- Language: The user can choose a language to learn (e.g., English, German, Italian, French, Spanish).
- Category: The category of words the player can learn (e.g., fruits, animals, colors).
The game elements are stored in DynamoDB, with
category
as the primary key and english
as the sort key. The attributes include translations of the English word, audio files, and an image file corresponding to the word.{
}
"category": { "S": "animals"
}, "english": { "S": "dog"
}, "english_audio_url": { "S": "dog_english.mp3"
}, "french": { "S": "chien"
}, "french_audio_url": { "S": "dog_french.mp3"
}, "german": { "S": "Hund"
}, "german_audio_url": { "S": "dog_german.mp3"
}, "image_url": { "S": "dog.png"
}, "italian": { "S": "cane"
}, "italian_audio_url": { "S": "dog_italian.mp3"
}, "spanish": { "S": "perro"
}, "spanish_audio_url": { "S": "dog_spanish.mp3"
}}
AWS SAM simplifies serverless application development. Start by creating a new project:
sam init --name language-game --runtime python3.13 --app-template hello-world
This command creates the following directory structure:
.
├── events
│ └── event.json
├── hello_world
│ ├── app.py
│ ├── __init__.py
│ └── requirements.txt
├── __init__.py
├── README.md
├── samconfig.toml
├── template.yaml
└── tests
├── integration
│ └── test_api_gateway.py
├── requirements.txt
└── unit
└── test_handler.py
├── events
│ └── event.json
├── hello_world
│ ├── app.py
│ ├── __init__.py
│ └── requirements.txt
├── __init__.py
├── README.md
├── samconfig.toml
├── template.yaml
└── tests
├── integration
│ └── test_api_gateway.py
├── requirements.txt
└── unit
└── test_handler.py
Key files:
template.yaml
: SAM template for provisioning AWS infrastructurehello_world/app.py
: Lambda function to serve as the backend
Replace the content of
template.yaml
with the following: (you can also get it from the Git Repo: https://github.com/DevOpsBug/AWS_LanguageGame)AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources
: LanguageGameTable
: Type: AWS::DynamoDB::Table
Properties
: TableName: language-game
AttributeDefinitions
: - AttributeName: category
AttributeType: S
- AttributeName: english
AttributeType: S
KeySchema
: - AttributeName: category
KeyType: HASH
- AttributeName: english
KeyType: RANGE
BillingMode: PAY_PER_REQUEST
LanguageGameLambda
: Type: AWS::Serverless::Function
Properties
: CodeUri: lambda/
Handler: app.lambda_handler
Runtime: python3.9
Environment
: Variables
: AWS_DYNAMODB_TABLE_NAME: !Ref LanguageGameTable
Policies
: - DynamoDBReadPolicy
: TableName: !Ref LanguageGameTable
Events
: LanguageGameApi
: Type: HttpApi
Properties
: Path: /language-game
Method: GET
LanguageGameBucket
: Type: AWS::S3::Bucket
Properties
: BucketName: <globally_unique_bucket_name>
PublicAccessBlockConfiguration
: BlockPublicAcls: true
LanguageGameCloudFrontDistribution
: Type: AWS::CloudFront::Distribution
Properties
: DistributionConfig
: Origins
: - Id: LanguageGameBucket
DomainName: !GetAtt LanguageGameBucket.RegionalDomainName
Enabled: true
Deploy the infrastructure:
sam build
sam deploy --guided
sam deploy --guided
Update
app.py
: (you can also get it from the Git Repo: https://github.com/DevOpsBug/AWS_LanguageGame)import
boto3import
jsonimport
osimport
randomdynamo_client = boto3.client('dynamodb'
)def lambda_handler
(event, context): table_name = os.environ.get('AWS_DYNAMODB_TABLE_NAME'
) category = event['queryStringParameters']['category'
] language = event['queryStringParameters']['language'
] response = dynamo_client.
query( TableName=
table_name, KeyConditionExpression='category = :category'
, ExpressionAttributeValues={':category': {'S'
: category}})
items = response['Items'
] correct_item = random.
choice(items) return
{ 'statusCode': 200
, 'body': json.
dumps({ 'word': correct_item[language]['S'
], 'audioUrl': correct_item[f"{language}_audio_url"]['S'
], 'correctImage': correct_item['image_url']['S'
]})
}
Clone the GitHub repository containing the frontend code and deploy the static files to the S3 bucket.
S3BUCKETNAME="<bucketname>"
./scripts/deploy_frontend.sh- Replace with the name of your newly created bucket.
- This will sync the static frontend files to your bucket
Now the only thing missing are the game contents. For this the only manual step is to gather image files and make sure the filename (jpg or png) corresponds to the english word. For example a picture of a dog should be named dog.jpg or dog.png. All pictures for one category must be placed in a local folder. Now the real magic happens in the Python Script scripts/add-new-game-objects.py which will perform the following steps:
- iterate over the local directory containing the images
- upload the images to the Amazon S3 bucket with prefix images/
- extract the english word from the filename
- translate the word into the foreign languages using Amazon Translate
- generate audio files for each language using Amazon Polly
- upload the audio files to the Amazon S3 bucket with prefix audio/
- insert all the metadata (words, translations, urls) into the DynamoDB table
To run the script you must:
- make sure your aws cli is setup with proper permissions
- modify the IMAGE_DIR and CATEGORY variables to match your requirements
- set Environment Variables S3_BUCKET_NAME and DYNAMODB_TABLE_NAME
export S3_BUCKET_NAME=
<bucketname>export DYNAMODB_TABLE_NAME=
<tablename>- run the script
# python3 add-new-game-objects.py
When the script is finished the DynamoDB table should be populated with data and the S3 Bucket contains the image and audio files. You should now go to the console and see the objects.
- Access your game through the CloudFront distribution URL.
- Select a language and category to start playing.
This is just the beginning for the Language Game. In the future, I plan to:
- Expand the vocabulary and language options.
- Incorporate AI models for personalized learning.
- Develop mobile-friendly versions to enhance accessibility.
- Collaborate with educators to refine the app’s educational impact.
The Language Game is more than a project—it’s a blend of professional growth and personal passion. By leveraging AWS services, I was able to create an impactful application that combines serverless architecture with AI-driven capabilities.
This journey has deepened my understanding of AWS and inspired me to keep exploring the potential of serverless solutions. If you’re interested in building your own serverless applications, don’t hesitate to start small, experiment, and leverage tools like Amazon Q to guide you along the way!
Have questions or thoughts? Let’s connect in the comments below!
Visit DevOpsBug for more intersting posts, projects and tutorials.