Search code examples
windowspowershellaws-code-deploy

How to reference a file in an AWS CodeDeploy package at execution?


I want to include a database upgrade script in my AWS CodeDeploy package, but I don't see how to specify a path to it.

I'm successfully triggering PowerShell scripts, and I have one that calls sqlcmd.exe and I want to pass sqlcmd a script to run.

When I print out the current working directory with Get-Location it shows C:\Windows\system32. So it seems the only way I would be able to reference it would be to know the current package path.

Is there a way to determine the current current package path within a deployment script?

Edit - My setup

enter image description here

version: 0.0
os: windows
files:
  - source: .\source
    destination: C:\inetpub\gentest.vanhookservice.com\dev
hooks:
    BeforeInstall:
        - location: .\scripts\db-backup-test.ps1
          timeout: 6000
        - location: .\scripts\code-backup-gentest.ps1
          timeout: 6000
          runas: Administrator
        - location: .\scripts\db-upgrade-test.ps1
          timeout: 6000

the db-upgrade-test.ps1:

# Fail on all errors
$ErrorActionPreference = 'Stop'

# Are you running in 32-bit mode?
#   (\SysWOW64\ = 32-bit mode)

if ($PSHOME -like "*SysWOW64*")
{
  Write-Warning "Restarting this script under 64-bit Windows PowerShell."

  # Restart this script under 64-bit Windows PowerShell.
  #   (\SysNative\ redirects to \System32\ for 64-bit mode)

  & (Join-Path ($PSHOME -replace "SysWOW64", "SysNative") powershell.exe) -File `
    (Join-Path $PSScriptRoot $MyInvocation.MyCommand) @args

  # Exit 32-bit script.

  Exit $LastExitCode
}

echo "Upgrading test database..."
sqlcmd.exe -S vhs-awsdev-sql1 -d JobManagerDev -i ..\database\upgrade.sql
# Test if the sqlcmd.exe command exited with a success or error condition
if ($? -eq "False")
{
   throw "sqlcmd.exe failed with exit code $LastExitCode"
}
echo "Test database upgrade complete." 

The problem is the ..\database\upgrade.sql reference. I also tried .\database\upgrade.sql because that's how the scripts are referenced in appspec.yml, but the real problem is the current working directory is actually C:\Windows\system32


Solution

  • The $PSScriptRoot used in the 64bit logic is what I wanted.

    The current database upgrade script looks like this:

    # Fail on all errors
    $ErrorActionPreference = 'Stop'
    
    # Are you running in 32-bit mode?
    #   (\SysWOW64\ = 32-bit mode)
    
    if ($PSHOME -like "*SysWOW64*")
    {
      Write-Warning "Restarting this script under 64-bit Windows PowerShell."
    
      # Restart this script under 64-bit Windows PowerShell.
      #   (\SysNative\ redirects to \System32\ for 64-bit mode)
    
      & (Join-Path ($PSHOME -replace "SysWOW64", "SysNative") powershell.exe) -File `
        (Join-Path $PSScriptRoot $MyInvocation.MyCommand) @args
    
      # Exit 32-bit script.
    
      Exit $LastExitCode
    }
    
    echo "Upgrading production database..."
    echo "PSScriptRoot: $PSScriptRoot"
    sqlcmd.exe -S vhs-sql1 -d JobManager -i "$PSScriptRoot\..\database\upgrade.sql"
    # Test if the sqlcmd.exe command exited with a success or error condition
    if ($LastExitCode -ne 0)
    {
        throw "sqlcmd.exe failed to run, exiting with the code $LastExitCode"
    }
    echo "Production database upgrade complete."
    

    Note the updated sqlcmd.exe line