/*
* Copyright 2011-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.cloudformation.AmazonCloudFormation;
import com.amazonaws.services.cloudformation.AmazonCloudFormationClient;
import com.amazonaws.services.cloudformation.model.CreateStackRequest;
import com.amazonaws.services.cloudformation.model.DeleteStackRequest;
import com.amazonaws.services.cloudformation.model.DescribeStackResourcesRequest;
import com.amazonaws.services.cloudformation.model.DescribeStacksRequest;
import com.amazonaws.services.cloudformation.model.Stack;
import com.amazonaws.services.cloudformation.model.StackResource;
import com.amazonaws.services.cloudformation.model.StackStatus;
/**
* This sample demonstrates how to make basic requests to AWS CloudFormation
* using the AWS SDK for Java.
* <p>
* <b>Prerequisites:</b> You must have a valid Amazon Web Services developer
* account, and be signed up to use AWS CloudFormation. For more information on
* AWS CloudFormation, see http://aws.amazon.com/cloudformation.
* <p>
* Fill in your AWS access credentials in the provided credentials file
* template, and be sure to move the file to the default location
* (~/.aws/credentials) where the sample code will load the credentials from.
* <p>
* <b>WANRNING:</b> To avoid accidental leakage of your credentials, DO NOT keep
* the credentials file in your source directory.s
*/
public class CloudFormationSample {
public static void main(String[] args) throws Exception {
/*
* The ProfileCredentialsProvider will return your [default]
* credential profile by reading from the credentials file located at
* (~/.aws/credentials).
*/
AWSCredentials credentials = null;
try {
credentials = new ProfileCredentialsProvider().getCredentials();
} catch (Exception e) {
throw new AmazonClientException(
"Cannot load the credentials from the credential profiles file. " +
"Please make sure that your credentials file is at the correct " +
"location (~/.aws/credentials), and is in valid format.",
e);
}
AmazonCloudFormation stackbuilder = new AmazonCloudFormationClient(credentials);
Region usWest2 = Region.getRegion(Regions.US_WEST_2);
stackbuilder.setRegion(usWest2);
System.out.println("===========================================");
System.out.println("Getting Started with AWS CloudFormation");
System.out.println("===========================================\n");
String stackName = "CloudFormationSampleStack";
String logicalResourceName = "SampleNotificationTopic";
try {
// Create a stack
CreateStackRequest createRequest = new CreateStackRequest();
createRequest.setStackName(stackName);
createRequest.setTemplateBody(convertStreamToString(CloudFormationSample.class.getResourceAsStream("CloudFormationSample.template")));
System.out.println("Creating a stack called " + createRequest.getStackName() + ".");
stackbuilder.createStack(createRequest);
// Wait for stack to be created
// Note that you could use SNS notifications on the CreateStack call to track the progress of the stack creation
System.out.println("Stack creation completed, the stack " + stackName + " completed with " + waitForCompletion(stackbuilder, stackName));
// Show all the stacks for this account along with the resources for each stack
for (Stack stack : stackbuilder.describeStacks(new DescribeStacksRequest()).getStacks()) {
System.out.println("Stack : " + stack.getStackName() + " [" + stack.getStackStatus().toString() + "]");
DescribeStackResourcesRequest stackResourceRequest = new DescribeStackResourcesRequest();
stackResourceRequest.setStackName(stack.getStackName());
for (StackResource resource : stackbuilder.describeStackResources(stackResourceRequest).getStackResources()) {
System.out.format(" %1$-40s %2$-25s %3$s\n", resource.getResourceType(), resource.getLogicalResourceId(), resource.getPhysicalResourceId());
}
}
// Lookup a resource by its logical name
DescribeStackResourcesRequest logicalNameResourceRequest = new DescribeStackResourcesRequest();
logicalNameResourceRequest.setStackName(stackName);
logicalNameResourceRequest.setLogicalResourceId(logicalResourceName);
System.out.format("Looking up resource name %1$s from stack %2$s\n", logicalNameResourceRequest.getLogicalResourceId(), logicalNameResourceRequest.getStackName());
for (StackResource resource : stackbuilder.describeStackResources(logicalNameResourceRequest).getStackResources()) {
System.out.format(" %1$-40s %2$-25s %3$s\n", resource.getResourceType(), resource.getLogicalResourceId(), resource.getPhysicalResourceId());
}
// Delete the stack
DeleteStackRequest deleteRequest = new DeleteStackRequest();
deleteRequest.setStackName(stackName);
System.out.println("Deleting the stack called " + deleteRequest.getStackName() + ".");
stackbuilder.deleteStack(deleteRequest);
// Wait for stack to be deleted
// Note that you could used SNS notifications on the original CreateStack call to track the progress of the stack deletion
System.out.println("Stack creation completed, the stack " + stackName + " completed with " + waitForCompletion(stackbuilder, stackName));
} catch (AmazonServiceException ase) {
System.out.println("Caught an AmazonServiceException, which means your request made it "
+ "to AWS CloudFormation, but was rejected with an error response for some reason.");
System.out.println("Error Message: " + ase.getMessage());
System.out.println("HTTP Status Code: " + ase.getStatusCode());
System.out.println("AWS Error Code: " + ase.getErrorCode());
System.out.println("Error Type: " + ase.getErrorType());
System.out.println("Request ID: " + ase.getRequestId());
} catch (AmazonClientException ace) {
System.out.println("Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with AWS CloudFormation, "
+ "such as not being able to access the network.");
System.out.println("Error Message: " + ace.getMessage());
}
}
// Convert a stream into a single, newline separated string
public static String convertStreamToString(InputStream in) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder stringbuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
stringbuilder.append(line + "\n");
}
in.close();
return stringbuilder.toString();
}
// Wait for a stack to complete transitioning
// End stack states are:
// CREATE_COMPLETE
// CREATE_FAILED
// DELETE_FAILED
// ROLLBACK_FAILED
// OR the stack no longer exists
public static String waitForCompletion(AmazonCloudFormation stackbuilder, String stackName) throws Exception {
DescribeStacksRequest wait = new DescribeStacksRequest();
wait.setStackName(stackName);
Boolean completed = false;
String stackStatus = "Unknown";
String stackReason = "";
System.out.print("Waiting");
while (!completed) {
List<Stack> stacks = stackbuilder.describeStacks(wait).getStacks();
if (stacks.isEmpty())
{
completed = true;
stackStatus = "NO_SUCH_STACK";
stackReason = "Stack has been deleted";
} else {
for (Stack stack : stacks) {
if (stack.getStackStatus().equals(StackStatus.CREATE_COMPLETE.toString()) ||
stack.getStackStatus().equals(StackStatus.CREATE_FAILED.toString()) ||
stack.getStackStatus().equals(StackStatus.ROLLBACK_FAILED.toString()) ||
stack.getStackStatus().equals(StackStatus.DELETE_FAILED.toString())) {
completed = true;
stackStatus = stack.getStackStatus();
stackReason = stack.getStackStatusReason();
}
}
}
// Show we are waiting
System.out.print(".");
// Not done yet so sleep for 10 seconds.
if (!completed) Thread.sleep(10000);
}
// Show we are done
System.out.print("done\n");
return stackStatus + " (" + stackReason + ")";
}
}