CodeDeploy on Windows EC2 Permission Denied

5.7k Views Asked by At

Just looking for some advice on doing CodeDeploy on Windows. I've used it for a year on Linux boxes, this is my first Windows Server on EC2 and I can't seem to get past "Permission Denied" errors.

I've changed the permissions in Windows on the folders, but the Deploy is failing on the Install step on CodeDeploy.

Error CodeUnknownError
Script Name
MessagePermission denied - c:/inetpub/render
Log Tail

appspec.yml

version: 0.0
os: windows
files:
 - source: /
   destination: /inetpub/render
hooks:
  AfterInstall:
    - location: aws/scripts/deploy.bat
      runas: administrator
      timeout: 1200

I've tried both Windows and Linux style pathing (C:\inetpub\render) because examples aren't clear, but nothing has worked.

3

There are 3 best solutions below

4
On

The error "Permision Denied" on a Windows Instance while using CodeDeploy is usually because one or more files that you are trying to depoloy is already in use. (May be a .exe already running, A file open in notepad etc.).
Please see if this is the case and if so either manually stop the process that are using these files or you can use the ApplicationStop,BeforeInstall hooks to configure scripts that will stop any running process before going in for Install.

0
On

I kept having similar issues. Upon analyzing locking processes I figured its previous deployment not closing file handles in some circumstances. Looks like codedeploy bug.

I put together below powershell functions and call Stop-PreviousDeploymentProcesses on aplicationstop or beforeinstall hooks which kills those previous deployment related processes.

Hope it works for you too.

function Get-PreviousDeploymentId {
         $dirs = Get-ChildItem -Path "C:\ProgramData\Amazon\CodeDeploy" -Directory -Recurse | Where-Object { $_.Name -match "d-\w{8}" }
        $previousDeploymentDir = $dirs | Sort-Object CreationTime -Descending | Select-Object -Skip 1 -First 1
        return $previousDeploymentDir.Name
}

function Stop-PreviousDeploymentProcesses {
    $previousDeployId=Get-PreviousDeploymentId
    # make sure this is codedeploy deploymentid
    if ( $previousDeployId -match "d-\w{8}" ) {
        $processes = $(Get-WmiObject win32_process -filter "CommandLine LIKE '%$($previousDeployId)%'");
        if ( $Null -ne $processes ) {
            foreach($proc in $processes) {
                try {
                    $proc.Terminate()
                    Write-Output "OK: Terminated process '$($proc.ProcessId) $($proc.Name) $($proc.CommandLine)' related to previous deploymentId $previousDeployId"
                }
                catch {
                    Write-Warning "Failed to terminate process $($proc.ProcessId). Error: $_"
                }
            }
        }
    }
}
0
On

In my case the "Permission denied @ unlink_internal" was caused by dotnet.exe process locking one of the dll's. You can find out what locks your file using Microsoft Process Explorer. You can then update your appspec.yml BeforeInstall hook to kill the process before files are updated:

version: 0.0
os: windows
files:
  - source: \files
    destination: C:\inetpub\wwwroot\yoursite
hooks:
  BeforeInstall:
    - location: stopsite.bat
      timeout: 300
      runas: Administrator
  AfterInstall:
    - location: startsite.bat
      timeout: 300
      runas: Administrator

Where stopsite.bat contains the following commands:

C:\Windows\System32\inetsrv\appcmd stop site "yoursite"
taskkill /IM "dotnet.exe" /F