From 'Permission Denied' to Production: My AWS & Terraform Journey
Source: Dev.to

The Pivot From DigitalOcean to AWS
I was following a course that used DigitalOcean to deploy the Java app. DigitalOcean kept rejecting my cards because I’m in Nigeria, so I hit a brick wall.
Instead of giving up, I remembered my #30ofAWSTerraform challenge. AWS is more complex, but it’s the industry leader. I decided to translate the DigitalOcean “Firewall” into an AWS Security Group and gain real‑world experience.
1. Provisioning Infrastructure with Terraform
My goal was to use Infrastructure as Code (IaC) to create an EC2 instance. I used the aws_instance and aws_key_pair resources.
The Challenge: SSH Key Management
Passing the public key as a raw string variable caused formatting errors.
The Solution
Use Terraform’s file() function to read the public key directly from disk, ensuring the exact bytes on my Windows machine are sent to AWS.
resource "aws_key_pair" "my_ssh_key" {
key_name = "zacks-key"
public_key = file("C:/Users/Public/id_aws.pub")
}
Terraform Code Samples


2. The Battle of AMI IDs and Usernames
Even after the instance was “running,” I couldn’t SSH in. I kept seeing InvalidAMIID.NotFound or Permission denied (publickey).
Lessons Learned
| Issue | What I Learned |
|---|---|
| Region Specificity | AMI IDs are region‑specific. An Ubuntu AMI for London won’t work in North Virginia (us-east-1). |
| Architecture Matters | t2.micro requires an x86_64 image. Using an ARM‑based AMI results in a “Not Found” error. |
| Default User | Each OS has its own default SSH user: ec2-user for Amazon Linux, ubuntu for Ubuntu, etc. |
3. Deploying the Application (The JAR File)
Once I could SSH into the server, I needed to copy my Java artifact from build/libs to the EC2 instance.
The Tool: SCP (Secure Copy)
scp -i C:\Users\Public\id_aws "C:\Users\...\java-app-1.0-SNAPSHOT.jar" ubuntu@:/home/ubuntu/

Translating Firewall to Security Group
When the instructor added a firewall rule on DigitalOcean, I mirrored it in AWS by updating the Security Group in Terraform to open Port 8080, allowing traffic to reach my Spring Boot app.
4. Linux User Management & Security
For better security, I created a personal user zacks.
Steps Taken
-
Create the user
sudo adduser zacks -
Grant sudo privileges
sudo usermod -aG sudo zacks -
Fix SSH authorized keys
I mistakenly named the key fileAuthentication_keys. Linux expectsauthorized_keys. I also corrected ownership and permissions:sudo mv /home/zacks/.ssh/Authentication_keys /home/zacks/.ssh/authorized_keys sudo chown -R zacks:zacks /home/zacks/.ssh sudo chmod 600 /home/zacks/.ssh/authorized_keys
Conclusion
Today was a masterclass in troubleshooting. I learned that DevOps isn’t just about writing code; it’s about being adaptable. When one cloud door closed, I used Terraform to open a better one on AWS.
(image placeholder – replace with the actual URL)

Infrastructure is live, the JAR is running, and the “Whitelabel Error Page” never looked so beautiful!

