Description
Sharing an IAM role between an internet-exposed EC2 instance and an internal workload can give the exposed instance unnecessary access to internal data. Compromise can then affect resources within that role’s permissions.
A public subnet alone does not establish reachability. Check actual addressing, routes and security groups, and separate roles according to workload permissions rather than network names alone.
Potential impact
- Compromise of an exposed instance can affect data accessible through the shared role.
- Sharing across distinct workloads makes permission changes and attribution harder to assess.
Remediation
- Use separate roles and instance profiles where workload permission requirements differ. Different profile names with the same role or permissions are not sufficient.
- Restrict AWS operations and resources, and test required access and rejection of unnecessary access after profile changes.
Examples
These excerpts require the AMI, VPC module, roles and separate private-workload profile to be supplied. The after-example reference aws_iam_instance_profile.test_profile3 must attach a separate role for the internal workload.
Before
hcl
resource "aws_iam_instance_profile" "example" {
name = "test_profile"
role = aws_iam_role.test_role.name
}
resource "aws_instance" "public_instance" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
subnet_id = module.vpc.public_subnets[0]
iam_instance_profile = aws_iam_instance_profile.example.name
}
resource "aws_instance" "private_instance" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
subnet_id = module.vpc.private_subnets[0]
iam_instance_profile = aws_iam_instance_profile.example.name
}
After
hcl
resource "aws_iam_instance_profile" "public_profile" {
name = "test_profile"
role = aws_iam_role.test_role2.name
}
resource "aws_instance" "public_instance" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
subnet_id = module.vpc.public_subnets[0]
iam_instance_profile = aws_iam_instance_profile.public_profile.name
}
resource "aws_instance" "private_instance" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
subnet_id = module.vpc.private_subnets[0]
iam_instance_profile = aws_iam_instance_profile.test_profile3.name
}
Explanation:
- Before: Both instances share one profile and role.
- After: Separates the profiles. Verify that each actually uses a distinct, least-privilege role.