Terraform IAM Policy for Automation

Not granting Administrator Access

Featured image

When you’re setting up an IAM role for Terraform, it’s essential to ensure you strike a balance between enabling automation and maintaining security. While it’s tempting to give broad permissions to make things easier, it can be risky. We neither want to become a bottleneck in the organization for the lack of permissions nor grant all full Administrator Access via the Managed Policy, so because of that we create a new IAM policy to achieve this.

Here are some AWS services and actions you might consider restricting:

1. IAM Resources

As mentioned earlier, you might want to deny actions related to deleting or modifying IAM roles, policies, or users. These are foundational security elements in AWS. You might also want to be cautious about allowing iam:PassRole which can be exploited if not correctly scoped.

2. AWS Organizational Changes

The organizations service can make high-level modifications to your AWS organization, like creating and deleting accounts. Most of the times this set of services and resources are not fully managed by Terraform, and they are managed in a separate root account or using the sofisticated ATF Service, but in any case, it is always a good practice to restrict the actions to these service.

3. Account Settings

Restricting the following are also important in a scenario on where the role or the account is compromised.

4. Key Management Service (KMS)

Deletion or modification of KMS keys can be catastrophic if data is encrypted with a key that gets deleted.

5. S3 Bucket Policies

You might want to prevent Terraform from deleting S3 buckets or changing their policies, given the potential for data loss or exposure and even so if you are working in an industry where data retrieval and archival is really important.

6. CloudTrail

Ensure that Terraform can’t turn off your auditing for trails.

7. Direct Connect and VPN

Changes here can lead to a loss of connectivity in your current setups.

8. RDS Snapshots

Protect against accidental deletion of database backups.

9. Route 53

Especially if using AWS for domain registration, you wouldn’t want domains to be deleted.

10. GuardDuty and Shield

Ensure that your security monitoring and protection can’t be turned off.

Remember, the specifics of what you should restrict will depend heavily on your specific use-case and infrastructure. The above are just suggestions to get you started and it’s what has work for me multiple times, applying it in very different set of clients and environments. Regularly reviewing and auditing IAM permissions and ensuring least privilege principles can be an effective way to maintain security. Always remeber the Shift left methodology.

Here is the IAM Policy that works for us, in the first statement we enable all actions on all resources, and then, in the second statement we restrict the specific services and actions that a Terraform role should need on day to day operations, as these changes might be manged outside an automation tool using Terraform, and if they are not, we just confirm the actions and resource and enabled it in the IAM policy.

IAM Policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        },
        {
            "Effect": "Deny",
            "Action": [
                "iam:DeleteAccessKey",
                "iam:DeleteAccountAlias",
                "iam:DeleteAccountPasswordPolicy",
                "iam:DeleteGroup",
                "iam:DeleteGroupPolicy",
                "iam:DeleteInstanceProfile",
                "iam:DeleteLoginProfile",
                "iam:DeleteOpenIDConnectProvider",
                "iam:DeleteSAMLProvider",
                "iam:DeleteServerCertificate",
                "iam:DeleteServiceSpecificCredential",
                "iam:DeleteSigningCertificate",
                "iam:DeleteSSHPublicKey",
                "organizations:DeleteOrganization",
                "organizations:LeaveOrganization",
                "organizations:RemoveAccountFromOrganization",
                "aws-portal:ModifyAccount",
                "aws-portal:ModifyBilling",
                "aws-portal:ModifyPaymentMethods",
                "cloudtrail:DeleteTrail",
                "cloudtrail:StopLogging",
                "directconnect:Delete*",
                "ec2:DeleteVpnConnection",
                "ec2:DeleteVpnGateway",
                "rds:DeleteDBSnapshot",
                "guardduty:DeleteDetector",
                "shield:DeleteProtection",
                "codepipeline:DeletePipeline"
            ],
            "Resource": "*"
        }
    ]
}

That’s it, that’s the IAM policy that has worked for us in order to have Terraform execute our plans and apply from a GitHub runner allowing the usage of multiple services and restricting the ones that might not be fully needed.

Build On!