# No Keys, No Risk - Secure Secrets with AWS Secrets Manager & EC2 IAM Roles

* * *

## Securely Managing Application Secrets Using AWS Secrets Manager and IAM Roles (No Access Keys)

**Learn how real companies securely fetch secrets from AWS Secrets Manager without ever storing AWS access keys on the instance.**

In this hands-on guide you will:

*   Launch an EC2 instance with an IAM role (no credentials)
    
*   Create a secret in AWS Secrets Manager
    
*   Fetch it using AWS CLI, Bash script, and Node.js
    
*   Perform a live secret update (zero code change, zero redeploy)
    

This is exactly how production applications handle secrets in 2026.

* * *

### Why This Matters

Hardcoding secrets or storing AWS access keys on EC2 is one of the biggest security risks in the cloud.  
**The correct way:** Use AWS Secrets Manager + IAM Roles for EC2.

*   No access keys in code or environment variables
    
*   Automatic temporary credentials via IAM
    
*   Secrets encrypted at rest with AWS KMS
    
*   Live updates without redeploying your app
    

* * *

### Prerequisites

*   An AWS account
    
*   One Ubuntu EC2 instance (t3.medium or larger recommended)
    
*   IAM permissions to create roles and secrets
    

* * *

### Step 0: EC2 Setup (User Data)

When launching your Ubuntu EC2 instance, add this **User Data** script so AWS CLI is ready:

```shell
#!/bin/bash

sudo apt update -y
sudo snap install aws-cli --classic
```

* * *

### 1\. Create IAM Role for EC2 (Console)

1.  Go to **IAM → Roles → Create role**
    
2.  Trusted entity type: **AWS service → EC2**
    
3.  Attach permission policies: **SecretsManagerReadWrite** (managed policy)
    
4.  Role name: `SecretsManagerEC2Role`
    
5.  Create the role
    

* * *

### 2\. Attach the IAM Role to Your EC2 Instance

1.  Go to **EC2 → Instances**
    
2.  Select your instance → **Actions → Security → Modify IAM role**
    
3.  Choose `SecretsManagerEC2Role`
    
4.  Save
    

* * *

### 3\. Verify IAM Role (No Credentials Needed!)

SSH into your EC2 instance and run:

```bash
aws sts get-caller-identity
```

You should see your Account ID and the **Role ARN** (`arn:aws:iam::...:role/SecretsManagerEC2Role`).

**Important point to remember:**  
You never ran `aws configure`. The IAM role automatically provides temporary credentials.

* * *

### 4\. Create a Secret in AWS Secrets Manager

```bash
aws secretsmanager create-secret \
  --name db-secret-1 \
  --secret-string '{"username":"admin","password":"admin123"}' \
  --region us-east-1
```

* * *

### 5\. Fetch the Secret (CLI Demo)

```bash
aws secretsmanager get-secret-value \
  --secret-id db-secret-1 \
  --query SecretString \
  --output text \
  --region us-east-1
```

You will see:

```json
{"username":"admin","password":"admin123"}
```

* * *

### 6\. Bash Script Demo

Create the script:

```bash
vim app.sh
```

Paste:

```bash
#!/bin/bash

SECRET=$(aws secretsmanager get-secret-value \
  --secret-id db-secret-1 \
  --query SecretString \
  --output text \
  --region us-east-1)

echo "Fetched Secret:"
echo $SECRET
```

Make it executable and run:

```bash
chmod +x app.sh
./app.sh
```

* * *

### 7\. Node.js Application Demo (Real App Use Case)

Install Node.js and the AWS SDK:

```bash
sudo apt install -y nodejs npm
npm init -y
npm install aws-sdk
```

Create the app:

```bash
vim app.js
```

Paste:

```javascript
const AWS = require("aws-sdk");

const client = new AWS.SecretsManager({
  region: "us-east-1"   // ← your region
});

async function getSecret() {
  const data = await client
    .getSecretValue({ SecretId: "db-secret-1" })
    .promise();

  const secret = JSON.parse(data.SecretString);

  console.log("Username:", secret.username);
  console.log("Password:", secret.password);
}

getSecret();
```

Run it:

```bash
node app.js
```

* * *

### 8\. Live Update Demo (The Best Part)

Update the secret in AWS:

```bash
aws secretsmanager update-secret \
  --secret-id db-secret-1 \
  --secret-string '{"username":"admin","password":"secure123"}' \
  --region us-east-1
```

Run the Node.js app **again** (no code change!):

```bash
node app.js
```

You will now see the new password: `secure123`

This is production magic — secrets are dynamic.

* * *

### 9\. Security Best Practices (What Real Companies Do)

*   **Never** use `SecretsManagerReadWrite` in production (too broad)
    
*   Use least-privilege policy instead:
    

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue",
        "secretsmanager:DescribeSecret"
      ],
      "Resource": "arn:aws:secretsmanager:us-east-1:YOUR_ACCOUNT_ID:secret:db-secret-1*"
    }
  ]
}
```

*   Secrets are automatically encrypted with AWS KMS
    
*   Temporary credentials are rotated automatically by IAM
    

* * *

### Cleanup (Optional)

*   Delete the secret in AWS Secrets Manager console
    
*   Terminate the EC2 instance
    

* * *

### Final Takeaways

*   No AWS access keys stored anywhere
    
*   IAM roles provide secure, temporary credentials
    
*   Secrets are fully dynamic and encrypted
    
*   This is exactly how production workloads on EC2, ECS, EKS, and Lambda handle secrets
    

**Watch the full video** to see every step live: [YouTube Video](https://youtu.be/wHunyApig30)
