AWS CLI, AWS SDK & Spring Boot Integration
In this article, we will implement AWS integration with Spring Boot using the **AWS SDK for Java 2.x**.
Introduction
In the previous AWS articles, we understood AWS Regions, Availability Zones, IAM, billing, and account basics.
Now we will learn how Java/Spring Boot applications communicate with AWS services.
In real-time projects, developers usually interact with AWS in two ways:
- AWS CLI - Used by developers, DevOps engineers, and automation scripts.
- AWS SDK - Used inside applications like Java, Spring Boot, Python, Node.js, etc.
In this article, we will implement AWS integration with Spring Boot using the AWS SDK for Java 2.x.
What You Will Learn
By the end of this article, you will understand:
- What is AWS CLI?
- What is AWS SDK?
- Difference between AWS CLI and AWS SDK
- How to configure AWS credentials
- How Spring Boot connects with AWS
- How to upload files to Amazon S3 using Spring Boot
- Best practices for credentials and security
- Real-time architecture flow
High Level Architecture
flowchart TD
A[Developer Machine] --> B[AWS CLI]
A --> C[Spring Boot Application]
B --> D[AWS Account]
C --> E[AWS SDK for Java]
E --> F[Amazon S3]
E --> G[Amazon DynamoDB]
E --> H[Amazon SQS]
E --> I[Amazon SNS]
D --> F
1. What is AWS CLI?
AWS CLI stands for Amazon Web Services Command Line Interface.
It allows us to interact with AWS services using terminal commands.
Example:
aws s3 ls
aws ec2 describe-instances
aws iam list-users
Instead of opening AWS Console manually, we can use CLI commands to automate AWS tasks.
Common AWS CLI Use Cases
| Use Case | Example |
|---|---|
| List S3 buckets | aws s3 ls |
| Upload file to S3 | aws s3 cp file.txt s3://bucket-name/ |
| Check EC2 instances | aws ec2 describe-instances |
| Deploy scripts | Shell scripts using AWS CLI |
| CI/CD automation | GitHub Actions, Jenkins, GitLab |
2. What is AWS SDK?
AWS SDK is a set of libraries provided by AWS to interact with AWS services from application code.
For Java applications, we use:
AWS SDK for Java 2.x
Using AWS SDK, Spring Boot applications can directly call AWS services like:
Amazon S3
Amazon DynamoDB
Amazon SQS
Amazon SNS
Amazon SES
AWS Lambda
Secrets Manager
CloudWatch
AWS CLI vs AWS SDK
| Feature | AWS CLI | AWS SDK |
|---|---|---|
| Used By | Developers / DevOps | Application code |
| Access Type | Terminal commands | Java code |
| Example | aws s3 ls |
s3Client.listBuckets() |
| Best For | Manual tasks, automation scripts | Production applications |
| Language | Command line | Java, Python, Node.js, Go, etc. |
3. Real-Time Example
Assume you are building an application where users upload profile images.
The flow:
sequenceDiagram
participant User
participant UI
participant SpringBoot
participant S3
participant DB
User->>UI: Upload profile image
UI->>SpringBoot: POST /api/files/upload
SpringBoot->>S3: Upload file using AWS SDK
S3-->>SpringBoot: Return S3 object key
SpringBoot->>DB: Save file metadata
SpringBoot-->>UI: Upload successful
4. Prerequisites
Before implementation, you need:
AWS Account
IAM User or IAM Role
AWS CLI installed
Java 17+
Spring Boot 3+
Maven
IDE like IntelliJ
S3 Bucket
5. Install AWS CLI
macOS
brew install awscli
Verify:
aws --version
Expected output:
aws-cli/2.x.x
Windows
Download and install AWS CLI from the official AWS website.
Then verify:
aws --version
6. Configure AWS CLI
Run:
aws configure
It will ask:
AWS Access Key ID:
AWS Secret Access Key:
Default region name:
Default output format:
Example:
AWS Access Key ID: AKIAxxxxxxxxxxxx
AWS Secret Access Key: xxxxxxxxxxxxx
Default region name: us-east-1
Default output format: json
This creates two files:
~/.aws/credentials
~/.aws/config
Credentials File
cat ~/.aws/credentials
Example:
[default]
aws_access_key_id=AKIAxxxxxxxxxxxx
aws_secret_access_key=xxxxxxxxxxxxx
Config File
cat ~/.aws/config
Example:
[default]
region=us-east-1
output=json
7. Test AWS CLI
List S3 buckets:
aws s3 ls
Check current identity:
aws sts get-caller-identity
Expected output:
{
"UserId": "AIDA...",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/dev-user"
}
8. Create S3 Bucket
You can create from AWS Console or CLI.
Example:
aws s3 mb s3://codewithvenu-demo-bucket
Upload test file:
echo "Hello AWS" > hello.txt
aws s3 cp hello.txt s3://codewithvenu-demo-bucket/
List bucket files:
aws s3 ls s3://codewithvenu-demo-bucket/
9. Spring Boot Project Setup
Create Spring Boot project with:
Java 17
Spring Boot 3.x
Maven
Spring Web
Validation
Lombok optional
Project structure:
aws-springboot-demo
┣ src/main/java/com/codewithvenu/aws
┃ ┣ AwsSpringBootApplication.java
┃ ┣ config
┃ ┃ ┗ AwsS3Config.java
┃ ┣ controller
┃ ┃ ┗ FileUploadController.java
┃ ┣ service
┃ ┃ ┗ S3FileService.java
┃ ┗ dto
┃ ┗ FileUploadResponse.java
┣ src/main/resources
┃ ┗ application.yml
┗ pom.xml
10. Add Maven Dependencies
Update pom.xml:
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- AWS SDK S3 -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.25.60</version>
</dependency>
<!-- AWS SDK Auth -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>auth</artifactId>
<version>2.25.60</version>
</dependency>
<!-- Lombok Optional -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
11. Configure application.yml
server:
port: 8080
aws:
region: us-east-1
s3:
bucket-name: codewithvenu-demo-bucket
Important:
Do not store access keys directly in application.yml.
Avoid this:
aws:
access-key: AKIAxxxx
secret-key: xxxxx
This is not secure.
12. AWS S3 Configuration Class
Create:
src/main/java/com/codewithvenu/aws/config/AwsS3Config.java
package com.codewithvenu.aws.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
@Configuration
public class AwsS3Config {
@Value("${aws.region}")
private String awsRegion;
@Bean
public S3Client s3Client() {
return S3Client.builder()
.region(Region.of(awsRegion))
.credentialsProvider(DefaultCredentialsProvider.create())
.build();
}
}
How DefaultCredentialsProvider Works
AWS SDK checks credentials in this order:
flowchart TD
A[AWS SDK Starts] --> B[Check Environment Variables]
B --> C[Check Java System Properties]
C --> D[Check AWS Credentials File]
D --> E[Check ECS Task Role]
E --> F[Check EC2 Instance Role]
F --> G[Use Credentials]
This means locally it can use:
~/.aws/credentials
In AWS cloud, it can use:
IAM Role
That is why we should not hardcode access keys.
13. Create Response DTO
Create:
src/main/java/com/codewithvenu/aws/dto/FileUploadResponse.java
package com.codewithvenu.aws.dto;
public class FileUploadResponse {
private String fileName;
private String bucketName;
private String objectKey;
private String message;
public FileUploadResponse(String fileName, String bucketName, String objectKey, String message) {
this.fileName = fileName;
this.bucketName = bucketName;
this.objectKey = objectKey;
this.message = message;
}
public String getFileName() {
return fileName;
}
public String getBucketName() {
return bucketName;
}
public String getObjectKey() {
return objectKey;
}
public String getMessage() {
return message;
}
}
14. Create S3 File Service
Create:
src/main/java/com/codewithvenu/aws/service/S3FileService.java
package com.codewithvenu.aws.service;
import com.codewithvenu.aws.dto.FileUploadResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Service
public class S3FileService {
private final S3Client s3Client;
@Value("${aws.s3.bucket-name}")
private String bucketName;
public S3FileService(S3Client s3Client) {
this.s3Client = s3Client;
}
public FileUploadResponse uploadFile(MultipartFile file) throws IOException {
String objectKey = generateObjectKey(file.getOriginalFilename());
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.contentType(file.getContentType())
.build();
s3Client.putObject(
putObjectRequest,
RequestBody.fromBytes(file.getBytes())
);
return new FileUploadResponse(
file.getOriginalFilename(),
bucketName,
objectKey,
"File uploaded successfully"
);
}
private String generateObjectKey(String originalFileName) {
String timestamp = LocalDateTime.now()
.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
return "uploads/" + timestamp + "-" + originalFileName;
}
}
15. Create File Upload Controller
Create:
src/main/java/com/codewithvenu/aws/controller/FileUploadController.java
package com.codewithvenu.aws.controller;
import com.codewithvenu.aws.dto.FileUploadResponse;
import com.codewithvenu.aws.service.S3FileService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@RestController
@RequestMapping("/api/files")
public class FileUploadController {
private final S3FileService s3FileService;
public FileUploadController(S3FileService s3FileService) {
this.s3FileService = s3FileService;
}
@PostMapping("/upload")
public ResponseEntity<FileUploadResponse> uploadFile(
@RequestParam("file") MultipartFile file
) throws IOException {
FileUploadResponse response = s3FileService.uploadFile(file);
return ResponseEntity.ok(response);
}
}
16. Main Application Class
package com.codewithvenu.aws;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AwsSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(AwsSpringBootApplication.class, args);
}
}
17. Run Application
Start Spring Boot:
mvn spring-boot:run
Upload file using curl:
curl -X POST http://localhost:8080/api/files/upload \
-F "[email protected]"
Expected response:
{
"fileName": "hello.txt",
"bucketName": "codewithvenu-demo-bucket",
"objectKey": "uploads/20260625103045-hello.txt",
"message": "File uploaded successfully"
}
Verify from AWS CLI:
aws s3 ls s3://codewithvenu-demo-bucket/uploads/
18. Download File from S3
Add method in S3FileService:
public byte[] downloadFile(String objectKey) {
return s3Client.getObjectAsBytes(builder -> builder
.bucket(bucketName)
.key(objectKey)
.build()
).asByteArray();
}
Add controller endpoint:
@GetMapping("/download")
public ResponseEntity<byte[]> downloadFile(
@RequestParam String key
) {
byte[] fileContent = s3FileService.downloadFile(key);
return ResponseEntity.ok(fileContent);
}
Test:
curl "http://localhost:8080/api/files/download?key=uploads/20260625103045-hello.txt"
19. Delete File from S3
Add service method:
public String deleteFile(String objectKey) {
s3Client.deleteObject(builder -> builder
.bucket(bucketName)
.key(objectKey)
.build()
);
return "File deleted successfully: " + objectKey;
}
Add controller endpoint:
@DeleteMapping("/delete")
public ResponseEntity<String> deleteFile(
@RequestParam String key
) {
return ResponseEntity.ok(s3FileService.deleteFile(key));
}
Test:
curl -X DELETE "http://localhost:8080/api/files/delete?key=uploads/20260625103045-hello.txt"
20. IAM Permission Required
For this demo, the application needs S3 permissions.
Minimum IAM policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3ApplicationAccess",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::codewithvenu-demo-bucket",
"arn:aws:s3:::codewithvenu-demo-bucket/*"
]
}
]
}
Avoid giving full admin access.
Do not use:
AdministratorAccess
for application runtime.
21. Local Development Credentials
For local development, use:
aws configure
or environment variables:
export AWS_ACCESS_KEY_ID=your-access-key
export AWS_SECRET_ACCESS_KEY=your-secret-key
export AWS_REGION=us-east-1
Then run:
mvn spring-boot:run
22. Production Credentials
In production, do not use access keys.
Use IAM roles.
Example:
flowchart LR
A[Spring Boot App on EC2/ECS/EKS] --> B[IAM Role]
B --> C[Temporary Credentials]
C --> D[Amazon S3]
Production options:
| Platform | Recommended Auth |
|---|---|
| EC2 | IAM Instance Profile |
| ECS | ECS Task Role |
| EKS | IAM Role for Service Account |
| Lambda | Lambda Execution Role |
| Local Dev | AWS CLI profile |
23. Multiple AWS Profiles
You can configure multiple profiles:
aws configure --profile dev
aws configure --profile prod
Use profile:
aws s3 ls --profile dev
Run Spring Boot with profile:
export AWS_PROFILE=dev
mvn spring-boot:run
24. Common Errors and Fixes
Error 1: Unable to locate credentials
Unable to load credentials from any of the providers
Fix:
aws configure
aws sts get-caller-identity
Error 2: Access Denied
software.amazon.awssdk.services.s3.model.S3Exception: Access Denied
Fix:
Check IAM permissions:
s3:PutObject
s3:GetObject
s3:DeleteObject
s3:ListBucket
Also check bucket policy.
Error 3: Wrong Region
The bucket is in this region: us-east-1
Fix:
Update:
aws:
region: us-east-1
Error 4: Bucket Not Found
NoSuchBucket
Fix:
aws s3 ls
Check bucket name in:
aws:
s3:
bucket-name: your-bucket-name
25. Best Practices
Security Best Practices
Never hardcode access keys
Use IAM roles in production
Use least privilege permissions
Rotate access keys regularly
Use separate AWS accounts for dev/test/prod
Enable CloudTrail
Enable S3 bucket encryption
Block public access unless required
Application Best Practices
Validate file size
Validate file type
Generate unique object keys
Store metadata in database
Use pre-signed URLs for downloads
Use async processing for large files
Add retry and timeout configuration
Monitor failures using CloudWatch
26. Better Production Architecture
flowchart TD
A[User] --> B[React / Next.js UI]
B --> C[Spring Boot API]
C --> D[Validate File]
D --> E[Upload to S3]
E --> F[Save Metadata in DB]
F --> G[Return File URL]
C --> H[CloudWatch Logs]
E --> I[S3 Bucket Encryption]
C --> J[IAM Role]
27. Real-Time Enterprise Use Cases
| Use Case | AWS Service | Example |
|---|---|---|
| File upload | S3 | Profile image upload |
| Async processing | SQS | Process uploaded Excel file |
| Notification | SNS | Send upload success notification |
| Database | DynamoDB / RDS | Store file metadata |
| Secrets | Secrets Manager | Store DB password |
| Monitoring | CloudWatch | Logs and metrics |
| SES | Send user emails |
28. Interview Explanation
If interviewer asks:
How does Spring Boot connect to AWS?
Answer:
Spring Boot connects to AWS using AWS SDK for Java. We create AWS service clients like S3Client, DynamoDbClient, or SqsClient. These clients use region and credentials from the AWS default credentials provider chain. Locally, credentials usually come from ~/.aws/credentials. In production, credentials should come from IAM roles attached to EC2, ECS, EKS, or Lambda.
Why should we avoid hardcoding AWS keys?
Answer:
Hardcoded keys can be leaked through GitHub, logs, build artifacts, or shared configuration files. If leaked, attackers can access AWS resources. The best practice is to use IAM roles and temporary credentials in production.
AWS CLI vs AWS SDK?
Answer:
AWS CLI is used from the terminal for manual operations and automation scripts. AWS SDK is used inside application code to call AWS services programmatically.
29. Summary
In this article, we learned:
AWS CLI is used for command line access
AWS SDK is used for application integration
Spring Boot can connect to AWS using AWS SDK for Java 2.x
S3Client is used to upload, download, and delete files
Credentials should not be hardcoded
IAM roles are best for production
Least privilege access is mandatory
30. Complete Flow Recap
flowchart LR
A[Install AWS CLI] --> B[Configure Credentials]
B --> C[Test with aws sts get-caller-identity]
C --> D[Create S3 Bucket]
D --> E[Create Spring Boot App]
E --> F[Add AWS SDK Dependency]
F --> G[Create S3Client Bean]
G --> H[Upload File API]
H --> I[Test API]
I --> J[Verify File in S3]
Comments
Share a question, correction, or practical insight about this article.
Checking login status...
Loading approved comments...