Creating a Postgres Database for vCAC’s Core Appliance

I’m installing vCloud Automation Center (vCAC) in a lab and needed to set up a Postgres database on a server external to the vCAC core appliance.  I have zero experience with Postgres so it took the normal Googling around to find a solution.  For the Postgres database I used Postgres 9.3 on CentOS release 6.5.  The vCAC documentation says, “PostgreSQL or vPostgres version 9.2.4 or later is required to deploy a database on a separate server.”

Installing Postgres 9.3

https://wiki.postgresql.org/wiki/YUM_Installation has the instructions for installing Postgres via YUM.  I’ll reproduce some of them here.

First we need to exclude Postgres from the base CentOS repos.

Edit /etc/yum.repos.d/CentOS-Base.repo, in [base] and [updates] sections add
exclude=postgresql*

Now we can install the packages.  The postgressql-contrib package allows you to create extensions as required for vCAC.

yum -y localinstall http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm
yum -y install postgresql93-server postgresql-contrib

The default data directory for Postgres is /var/lib/pgsql/9.3/data

Configuring Postgres

Several changes needs to be made in order for the vCAC core appliance can connect to Postgres.  We need to make sure Postgres is not listening only on the loopback address and we need to allow the vCAC user to connect.

Edit /var/lib/pgsql/9.3/data/postgresql.conf and change
listen_addresses = ‘localhost’
to
listen_addresses = ‘*’

Edit /var/lib/pgsql/9.3/data/pg_hba.conf and change

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# IPv4 local connections:
#host    all             all             127.0.0.1/32            ident
to
host      all             all             all            md5

Instead of using ‘all’, you can specify the vCAC user and address, but I kept it simple for this lab.

Creating the vCAC database

Initialize Postgres
service postgresql-9.3 initdb

Configure Postgres to start on boot and start the service
chkconfig postgresql-9.3 on
service postgresql-9.3 start

Connect to Postgres
sudo -u postgres psql

Connect to the template1 database
\c template1

Create the vCAC user and vCAC database
CREATE USER vcac WITH NOCREATEDB NOCREATEROLE NOCREATEUSER INHERIT LOGIN ENCRYPTED password ‘vmware123’;
CREATE DATABASE vcac6a WITH OWNER vcac;

Connect to the vCAC database
\c vcac6a

Create extensions
CREATE EXTENSION “hstore”;
CREATE EXTENSION “uuid-ossp”;

Cleanup

Since we are now using an external database, we no longer need the embedded vPostgres service running on the vCAC core appliance so we can stop the service and configure it to not start on boot.

service vpostgres stop
chkconfig vpostgres off

If you’re using an external database for the vCAC core appliance, you can’t use the embedded vCO instance so we can stop the service and configure it to not start on boot.

service vco-server stop
chkconfig vco-server off


Changing VM storage policies in vCloud Director 5.5 with PowerCLI

I was recently asked to create a PowerCLI script for changing VM storage policies in a vCloud Director 5.5 environment.  It seems like vCloud Director 5.x doesn’t have the tightest integration with storage policies so it’s not as simple as running something like ‘Set-VM’ and passing a new storage policy.  The script searches for all VMs on a source storage policy and migrates them to the destination storage policy.   As always, test in your environment.

$vCDServer = 'vcd55.vmware.local'
$sourceStorageProfile = 'SiteA'
$destinationStorageProfile = 'SiteB'

# See https://communities.vmware.com/message/2372019. If you don't set the compatibility to 5.1, you'll receive the error:
# Exception calling "UpdateServerData" with "0" argument(s): "Bad request  - Unexpected JAXB Exception  - cvc-complex-type.2.4.a: Invalid content was found starting with element 'AdminAutoLogonEnabled'. One of '{"http://www.vmware.com/vcloud/v1.5":Link, WC[##other:"http://www.vmware.com/vcloud/v1.5"]}' is expected."
#    At line:10 char:1
#    + $GuestCustomization.UpdateServerData()
#    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
#    + FullyQualifiedErrorId : CloudException

[VMware.VimAutomation.Cloud.Views.CloudClient]::ApiVersionRestriction.ForceCompatibility("5.1")

connect-ciserver $vCDServer

# Get all VMs on the source policy
$vms = get-civm | ? { $_.ExtensionData.StorageProfile.Name -eq $sourceStorageProfile }

if ($vms) { # If we found any VMs. 
  $vms | % {
    $vm = $_  # Set the loop variable to something more readable
    write-host "Processing VM '$($vm)'"
    $newStorageProfile = $vm.orgvdc.ExtensionData.VdcStorageProfiles.VdcStorageProfile | ? { $_.name -eq $destinationStorageProfile }
    if ($newStorageProfile) {
      write-host "Found storage profile '$($newStorageProfile.name)' in org vDC '$($vm.orgvdc)'"
      write-host "Moving VM '$($vm.name)' to storage profile '$($destinationStorageProfile)'"
      $vm.ExtensionData.StorageProfile = $newStorageProfile
      try {
        $vm.ExtensionData.UpdateServerData()
      }
      Catch {
        write-host "Unable to update VM: " -NoNewLine -foregroundcolor "yellow"
        write-host "$($_.Exception.Message)" -foregroundcolor "red"
      }
      $newStorageProfile = $null
    }
    else {
      write-host "Unable to find storage profile '$($destinationStorageProfile)' in org vDC '$($vm.orgvdc)'"
    }
    write-host '-------------'
  }
}
else {
  write-host "No VMs found on storage profile '$($sourceStorageProfile)'"
}