How to Fix Terraform Permission Denied on CentOS 7


As a Senior DevOps Engineer, encountering “Permission Denied” errors during Terraform operations on a CentOS 7 environment is a common scenario. While seemingly straightforward, these errors often mask deeper issues related to file system permissions and, more critically on CentOS, SELinux policies. This guide provides a direct, professional approach to troubleshooting and resolving these issues.


Troubleshooting “Terraform Permission Denied” on CentOS 7

When Terraform reports a “Permission Denied” error on CentOS 7, it indicates that the user or process attempting to execute a Terraform command lacks the necessary operating system-level permissions to read, write, or execute files and directories critical to its operation.

1. The Root Cause: Why this happens on CentOS 7

The “Permission Denied” error from Terraform on CentOS 7 typically stems from one of two primary issues, often exacerbated by the system’s security posture:

  1. Incorrect File/Directory Permissions and Ownership (Standard POSIX):

    • Terraform needs to read its configuration (.tf files), write its state (terraform.tfstate), download and execute provider plugins (.terraform/plugins/), and manage its internal module cache (.terraform/modules/).
    • If the user running Terraform does not have appropriate read, write, or execute permissions for these files or their parent directories, operations will fail.
    • Common scenarios include:
      • Running Terraform as a non-root user where files were created by root.
      • Terraform working directory created with restrictive umask or chmod settings.
      • Attempting to write to a directory where the user only has read access.
  2. SELinux (Security-Enhanced Linux) Policies:

    • This is the most frequent and often overlooked cause on CentOS 7. Even if standard ls -l shows correct POSIX permissions (user, group, other), SELinux can still deny access.
    • SELinux operates by enforcing Mandatory Access Control (MAC), assigning security contexts (labels) to every file, directory, and process. If a process’s context is not permitted to access a file’s context by the loaded SELinux policy, access is denied, regardless of POSIX permissions.
    • Terraform often operates in directories with default contexts (e.g., user_home_t, default_t) that may not be explicitly allowed to be written to or executed by common process contexts, especially when running through automation tools or non-standard user contexts.

2. Quick Fix (CLI)

Before diving deep, attempt these immediate command-line fixes.

Identify the Problematic Path: The Terraform error message will usually specify the file or directory causing the “Permission Denied” issue. For example: Error: Failed to install provider ... permission denied Error: Failed to save state to "terraform.tfstate": permission denied

Once you know the path, proceed. Assume the Terraform project root is your current working directory.

  1. Correct Ownership and Permissions:

    • Navigate to your Terraform project directory.
    • Change Ownership: Ensure all files and directories are owned by the user account running Terraform. Replace $USER with your actual username.
      sudo chown -R $USER:$USER .
    • Adjust Permissions:
      • For directories (allowing read, write, execute for owner, read/execute for others):
        find . -type d -exec chmod 755 {} +
      • For files (allowing read/write for owner, read for others):
        find . -type f -exec chmod 644 {} +
      • Special Case: Terraform executable scripts/plugins: If the error specifically mentions a plugin or an executable within .terraform/, ensure it has execute permissions.
        find .terraform/plugins -type f -name 'terraform-provider-*' -exec chmod 755 {} +
      • Special Case: terraform.tfstate: This file contains sensitive information. You might want stricter permissions if it’s not being modified by CI/CD.
        chmod 600 terraform.tfstate # Read/write only for owner
  2. Temporarily Disable SELinux (Diagnostic ONLY):

    • This is a crucial diagnostic step to determine if SELinux is the root cause. Do not leave SELinux disabled in production.
    • Check current SELinux status:
      sestatus
    • Switch to Permissive mode (allows access but logs denials):
      sudo setenforce 0
    • Now, try running your Terraform command again (e.g., terraform init, terraform plan).
    • If the command succeeds, SELinux was indeed the problem. Remember to re-enable it:
      sudo setenforce 1
  3. Restore SELinux File Contexts:

    • If setenforce 0 fixed the issue, you likely have incorrect SELinux contexts. This often happens after moving files, copying, or tar operations.
    • Restore default contexts for the current directory and its contents:
      sudo restorecon -Rv .
    • This command attempts to apply the default SELinux contexts as defined by policy rules for the paths it finds. If the directory (e.g., /opt/terraform-projects) should have a specific context different from its parent or default, restorecon might not set the ideal context, but it’s a good first step.
    • For more precise control, you might need to use chcon or semanage fcontext (see Configuration Check).

3. Configuration Check

If the quick fixes don’t permanently resolve the issue, a deeper look at your system’s configuration is needed.

  1. SELinux Configuration (/etc/selinux/config):

    • Review the global SELinux configuration. This file determines if SELinux is enforcing, permissive, or disabled on boot.
    • cat /etc/selinux/config
    • For production, it should be enforcing. If you permanently set it to disabled previously, it effectively bypasses the issue but compromises security.
    • If setenforce 0 helped, and restorecon didn’t fix it, you might need to define a custom SELinux policy or change the file context permanently.
      • Check Current Contexts:
        ls -lZ . # For current directory
        ls -lZ terraform.tfstate # For a specific file
        Look for labels like unconfined_u:object_r:default_t:s0 or user_home_t.
      • Identify Denials: When SELinux is in permissive or enforcing mode, denials are logged. Check the audit logs:
        sudo tail -f /var/log/audit/audit.log | grep AVC
        This output is key to understanding which process (scontext) is being denied access to which file (tcontext) and for what operation (tclass).
      • Permanent Context Change (Advanced): Based on audit logs, you might need to set a specific context for your Terraform working directory. For example, to allow web servers to write to a directory, you might label it httpd_sys_rw_content_t. For a generic application directory, var_lib_t or usr_t might be appropriate.
        # Example: Allow application access to /opt/terraform-projects
        sudo semanage fcontext -a -t var_lib_t "/opt/terraform-projects(/.*)?"
        sudo restorecon -Rv /opt/terraform-projects
        Note: Choose the context carefully based on your use case and SELinux documentation.
  2. Filesystem Mount Options:

    • Check /etc/fstab for the mount options of the filesystem where your Terraform project resides.
    • cat /etc/fstab
      mount
    • Look for options like noexec (prevents execution of binaries), nosuid, or nodev, which could interfere with Terraform provider execution, especially if you’re running Terraform from a temporary directory or a volume with restrictive mounts (e.g., /tmp).
  3. User Environment and umask:

    • The umask value (check with umask command) influences the default permissions of newly created files and directories. A very restrictive umask (e.g., 077) could cause Terraform to create files that it cannot later read or modify if permissions are not explicitly set.
    • Verify the user’s $PATH environment variable. While not directly a “Permission Denied” issue for files, if terraform itself isn’t found, it’s a related execution problem.

4. Verification

After applying any fixes, thoroughly verify that Terraform can now perform all necessary operations.

  1. Clean and Re-initialize (if applicable):

    • If you’ve been troubleshooting heavily, consider removing the local state and cached plugins to force a clean start:
      rm -rf .terraform/ .terraform.lock.hcl terraform.tfstate*
    • Then, perform a full initialization:
      terraform init
      This step downloads providers and modules, which often triggers permission issues.
  2. Plan and Apply:

    • Run a plan to ensure configuration can be read and a plan generated:
      terraform plan
    • Attempt an apply to confirm write access to the state file and other directories:
      terraform apply -auto-approve # Use -auto-approve cautiously in production
  3. Check File Permissions and SELinux Contexts:

    • After terraform init and terraform apply, re-check the permissions and SELinux contexts of the .terraform/ directory, terraform.tfstate, and any other relevant files.
    • ls -lZ .terraform/
      ls -lZ terraform.tfstate
    • Ensure they align with expectations for the user running Terraform and your security policies.

By methodically working through file permissions, ownership, and especially SELinux contexts, you can effectively diagnose and resolve “Terraform Permission Denied” errors on CentOS 7, ensuring a stable and secure infrastructure deployment process. Remember that robust solutions often involve proper SELinux policy configuration rather than outright disabling it.