Skip to content

Commit

Permalink
Enhancements to cloudformation and AWSLambdaInvokeTask
Browse files Browse the repository at this point in the history
  • Loading branch information
donalhenry committed Dec 20, 2016
1 parent 2aa9332 commit 02743db
Show file tree
Hide file tree
Showing 13 changed files with 371 additions and 32 deletions.
16 changes: 8 additions & 8 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jacocoTestReport {
// checkstyle
checkstyle {
toolVersion = "7.1.2"
configFile = rootProject.file('config/checkstyle/checkstyle.xml')
configFile = project.file('config/checkstyle/checkstyle.xml')
}
checkstyleTest {
configFile = file("config/checkstyle/checkstyle-test.xml")
Expand Down Expand Up @@ -164,20 +164,20 @@ spotless {
licenseHeaderFile 'config/spotless/spotless.license.java'
importOrderFile 'config/spotless/spotless.importorder'
eclipseFormatFile 'config/spotless/spotless.eclipseformat.xml'

// Eclipse formatter screws up long literals with underscores inside of annotations (see issue #14)
// @Max(value = 9_999_999 L) // what Eclipse does
// @Max(value = 9_999_999L) // what I wish Eclipse did
custom 'Long literal fix', { it.replaceAll('([0-9_]+) [Ll]', '$1L') }

// Eclipse formatter puts excess whitespace after lambda blocks
// funcThatTakesLambdas(x -> {} , y -> {} ) // what Eclipse does
// funcThatTakesLambdas(x -> {}, y -> {}) // what I wish Eclipse did
custom 'Lambda fix', { it.replace('} )', '})').replace('} ,', '},') }

indentWithTabs()
endWithNewline()

customReplaceRegex 'Add space before comment asterisk', '^(\\t*)\\*', '$1 *'
// customReplaceRegex 'Remove indent before line comment', '^\\t*//', '//'
}
Expand Down Expand Up @@ -230,7 +230,7 @@ dependencies {
compile "com.google.guava:guava:$guavaVersion"
compile "commons-io:commons-io:1.4"
compile "org.projectlombok:lombok:$lombokVersion"

compile "com.amazonaws:aws-java-sdk-sts:$awsJavaSdkVersion"
compile "com.amazonaws:aws-java-sdk-s3:$awsJavaSdkVersion"
compile "com.amazonaws:aws-java-sdk-ec2:$awsJavaSdkVersion"
Expand All @@ -243,9 +243,9 @@ dependencies {
compile "com.amazonaws:aws-java-sdk-iam:$awsJavaSdkVersion"
compile "com.amazonaws:aws-java-sdk-sqs:$awsJavaSdkVersion"
compile "com.amazonaws:aws-java-sdk-sns:$awsJavaSdkVersion"

compile "jp.xet.spar-wings:spar-wings-awscli-config:$sparWingsVersion"

// tests
testCompile "junit:junit:$junitVersion"
testCompile "org.hamcrest:hamcrest-library:$hamcrestVersion"
Expand Down
63 changes: 63 additions & 0 deletions samples/06A-cloudformation/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
apply plugin: 'groovy'
apply plugin: 'jp.classmethod.aws.cloudformation'

apply from: 'deploy-dev.groovy'

import jp.classmethod.aws.gradle.s3.SyncTask
import jp.classmethod.aws.gradle.cloudformation.AmazonCloudFormationPluginExtension

group 'example'
version = "SNAPSHOT-${project.rootProject.startTime.format('yyMMddHHmm')}"

repositories {
mavenCentral()
}

dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.4'
compile 'com.amazonaws:aws-lambda-java-core:1.0.0'
}

task buildZip(type: Zip) {
from compileGroovy
from processResources
into('lib') {
from configurations.runtime
}
}

build.dependsOn buildZip

task uploadLamdbdaToS3(type: SyncTask) {
dependsOn build

delete true
bucketName "${cloudFormation.stackParams['pArtifactBucket']}"
prefix "${cloudFormation.stackParams['pArtifactPrefix']}/"
source file("$buildDir/distributions")
}

task updateStack (dependsOn: [uploadLamdbdaToS3, awsCfnMigrateStackAndWaitCompleted]) {
group 'CNN'
description "Creates/Updates $cloudFormation.stackName stack"
}

task deleteStack (dependsOn: awsCfnDeleteStackAndWaitCompleted) {
group 'CNN'
description "Deletes $cloudFormation.stackName stack"
}

awsCfnMigrateStack.mustRunAfter uploadLamdbdaToS3
awsCfnWaitStackComplete.loopTimeout = 10800 // = 3hr
awsCfnWaitStackDeleted.loopTimeout = 10800 // = 3hr

task getStackInfo {
doLast {
def stackName = cloudFormation.getStackOutputValue('StackName')
def lambdaArn = cloudFormation.getStackOutputValue('LambdaArn')

println """
$stackName
$lambdaArn"""
}
}
43 changes: 43 additions & 0 deletions samples/06A-cloudformation/cloudformation/HelloWorld.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
AWSTemplateFormatVersion: '2010-09-09'
Description: A groovy lambda
Parameters:
pArtifactBucket:
Description: The name of the S3 bucket that contains the source code of your Lambda
function.
Type: String
pArtifactPrefix:
Description: Prefix of the objects for the Lambdas
Type: String
pHelloWorldZipFile:
Description: The location and name of your source code .zip file.
Type: String
Resources:
HelloWorld:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket:
Ref: pArtifactBucket
S3Key:
Fn::Join:
- "/"
- - Ref: pArtifactPrefix
- Ref: pHelloWorldZipFile
Handler: example.Hello::myHandler
Runtime: java8
Description: A groovy lambda
MemorySize: 512
Timeout: 15
Role: arn:aws:iam::123456789012:role/lambda_basic_execution
Outputs:
StackName:
Description: StackName
Value:
Ref: AWS::StackName
LambdaArn:
Description: Lambda ARN
Value:
Fn::GetAtt:
- HelloWorld
- Arn
14 changes: 14 additions & 0 deletions samples/06A-cloudformation/cloudformation/stackpolicy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"Statement" : [
{
"Resource": "*",
"Effect": "Allow",
"Principal": "*",
"Action": [
"Update:Modify",
"Update:Delete",
"Update:Replace"
]
}
]
}
19 changes: 19 additions & 0 deletions samples/06A-cloudformation/deploy-dev.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
aws {
profileName = "default"
region = "ap-northeast-1"
}

cloudFormation {
stackName "HelloWorld-stack"
capabilityIam true
templateFile project.file('cloudformation/HelloWorld.yml')
stackPolicyFile project.file('cloudformation/stackpolicy.json')
onFailure 'DO_NOTHING'

stackParams ([
'pArtifactBucket': 'my-deploy-dev',
'pArtifactPrefix': 'helloworld-example',

'pHelloWorldZipFile' : "06A-cloudformation-${-> version}.zip"
])
}
15 changes: 15 additions & 0 deletions samples/06A-cloudformation/src/main/groovy/example/Hello.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// Borrowed from https://medium.com/@benorama/how-to-build-a-microservice-with-aws-lambda-in-groovy-4f7384c3b804#.9z2rs5hud
//

package example

import com.amazonaws.services.lambda.runtime.Context

class Hello {
Map myHandler(data, Context context) {
context.logger.log "received in groovy: $data"
[greeting: "Hello, ${data?.firstName} ${data?.lastName}".toString()]
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package jp.classmethod.aws.gradle.cloudformation;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -25,6 +27,7 @@
import lombok.Getter;
import lombok.Setter;

import org.apache.commons.io.FileUtils;
import org.gradle.api.GradleException;
import org.gradle.api.internal.ConventionTask;
import org.gradle.api.tasks.TaskAction;
Expand All @@ -38,6 +41,7 @@
import com.amazonaws.services.cloudformation.model.Parameter;
import com.amazonaws.services.cloudformation.model.Stack;
import com.amazonaws.services.cloudformation.model.Tag;
import com.google.common.base.Strings;

public class AmazonCloudFormationCreateChangeSetTask extends ConventionTask {

Expand All @@ -49,6 +53,10 @@ public class AmazonCloudFormationCreateChangeSetTask extends ConventionTask {
@Setter
private String cfnTemplateUrl;

@Getter
@Setter
private File cfnTemplateFile;

@Getter
@Setter
private List<Parameter> cfnStackParams = new ArrayList<>();
Expand All @@ -73,18 +81,14 @@ public AmazonCloudFormationCreateChangeSetTask() {
}

@TaskAction
public void creatChangeSet() throws InterruptedException {
public void createChangeSet() throws InterruptedException, IOException {
// to enable conventionMappings feature
String stackName = getStackName();
String cfnTemplateUrl = getCfnTemplateUrl();
List<String> stableStatuses = getStableStatuses();

if (stackName == null) {
throw new GradleException("stackName is not specified");
}
if (cfnTemplateUrl == null) {
throw new GradleException("cfnTemplateUrl is not specified");
}

AmazonCloudFormationPluginExtension ext =
getProject().getExtensions().getByType(AmazonCloudFormationPluginExtension.class);
Expand All @@ -100,21 +104,30 @@ public void creatChangeSet() throws InterruptedException {
}
}

private void createChangeSet(AmazonCloudFormation cfn) {
private void createChangeSet(AmazonCloudFormation cfn) throws IOException {
// to enable conventionMappings feature
String stackName = getStackName();
String cfnTemplateUrl = getCfnTemplateUrl();
List<Parameter> cfnStackParams = getCfnStackParams();
List<Tag> cfnStackTags = getCfnStackTags();
File cfnTemplateFile = getCfnTemplateFile();

String changeSetName = changeSetName(stackName);
getLogger().info("Create change set '{}' for stack '{}'", changeSetName, stackName);
CreateChangeSetRequest req = new CreateChangeSetRequest()
.withChangeSetName(changeSetName)
.withStackName(stackName)
.withTemplateURL(cfnTemplateUrl)
.withParameters(cfnStackParams)
.withTags(cfnStackTags);

// If template URL is specified, then use it
if (Strings.isNullOrEmpty(cfnTemplateUrl) == false) {
req.setTemplateURL(cfnTemplateUrl);
// Else, use the template file body
} else {
req.setTemplateBody(FileUtils.readFileToString(cfnTemplateFile));
}

if (isCapabilityIam()) {
req.setCapabilities(Arrays.asList(Capability.CAPABILITY_IAM.toString()));
}
Expand Down
Loading

0 comments on commit 02743db

Please sign in to comment.