Skip to content

Instantly share code, notes, and snippets.

@Gisleburt
Last active August 29, 2015 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gisleburt/86a20a5e79d33efec6f2 to your computer and use it in GitHub Desktop.
Save Gisleburt/86a20a5e79d33efec6f2 to your computer and use it in GitHub Desktop.
AWS Cloud Formation Precommit Validation
<?php
/**
* Class CloudFormationTemplateValidator
* @example
* echo 'Validating Cloud Formation Templates'.PHP_EOL;
* $hook = new CloudFormationTemplateValidator();
* $files = array_slice($argv, 1); // Get a list of files from arguments
* $files = $files ?: $hook->getFilesRecursively('/^.+\.json$/i', getcwd()); // ...or recursively from the working dir
* if(!$hook->validateCloudFormationTemplates($files)) {
* exit(1);
* }
*/
class CloudFormationTemplateValidator
{
protected $green = "\033[0;32m";
protected $red = "\033[0;31m";
protected $reset = "\033[0m";
protected function red($string)
{
return $this->red . $string . $this->reset;
}
protected function green($string)
{
return $this->green . $string . $this->reset;
}
protected function echoLine($string, $endLine = true)
{
echo $string . ($endLine ? PHP_EOL : '');
}
public function getFilesRecursively($dir = null, $pattern = '/^.+$/i')
{
$dir = $dir ?: getcwd();
$files = [];
if(!$files) {
$directoryIterator = new RecursiveDirectoryIterator($dir);
$iteratorIterator = new RecursiveIteratorIterator($directoryIterator);
$regexIterator = new RegexIterator($iteratorIterator, $pattern, RecursiveRegexIterator::GET_MATCH);
foreach($regexIterator as $filesIterator) {
foreach($filesIterator as $file) {
$files[] = $file;
}
}
}
return $files;
}
public function isAcfFile($fileName)
{
return substr($fileName, -5) === '.json';
}
public function getRealPathForFiles(array $files)
{
foreach($files as $key => $value) {
$files[$key] = realpath($value);
if (!$files[$key]) {
throw new Exception("Invalid file '$value'");
}
}
}
public function validateCloudFormationTemplates($files)
{
foreach($files as $file) {
if(!$this->isAcfFile($file)) {
echo "Skipped: $file". PHP_EOL;
continue;
}
$fileUrl = escapeshellarg("file://$file");
$returnStatus = 0;
$output = [];
exec("aws cloudformation validate-template --template-body $fileUrl 2>&1", $output, $returnStatus);
echo $returnStatus
? $this->red("Failure: ") . $file . PHP_EOL
: $this->green("Success: ") . $file . PHP_EOL
;
if($returnStatus)
{
foreach($output as $line) {
echo $line.PHP_EOL;
}
return false;
}
}
return true;
}
}
#!/bin/sh
git diff --cached --name-status | awk '$1 != "D" { print $2 }' | xargs php `git rev-parse --show-toplevel`/bin/validate.php
<?php
/**
* @example Use this as a pre-commit hook
* #!/bin/sh
* git diff --cached --name-status | awk '$1 != "D" { print $2 }' | xargs php `git rev-parse --show-toplevel`/bin/validate.php
*/
require_once 'CloudFormationTemplateValidator.php';
echo 'Validating Cloud Formation Templates'.PHP_EOL;
$hook = new CloudFormationTemplateValidator();
$files = array_slice($argv, 1); // Get a list of files from arguments
$files = $files ?: $hook->getFilesRecursively(getcwd()); // ...or recursively from the working dir
if(!$hook->validateCloudFormationTemplates($files)) {
exit(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment