4. Managing cloud environments

Managing environments manually with the management console does not scale and can become error-prone with the increasing complexity of the infrastructure. Amazon Web services offers a CloudFormation service that allows to define stack configuration templates and bootstrap the whole infrastructure with the services. In order to allow multiple stacks in parallel, each resource in the stack receives a unique physical name that contains some arbitrary generated name. In order to interact with the stack resources in a unified way Spring Cloud AWS allows developers to work with logical names instead of the random physical ones.

The next graphics shows a typical stack configuration.

CloudFormation overview

The Template File describes all stack resources with their logical name. The CloudFormation service parses the stack template file and creates all resources with their physical name. The application can use all the stack configured resources with the logical name defined in the template. Spring Cloud AWS resolves all logical names into the respective physical name for the application developer.

4.1 Automatic CloudFormation configuration

If the application runs inside a stack (because the underlying EC2 instance has been bootstrapped within the stack), then Spring Cloud AWS will automatically detect the stack and resolve all resources from the stack. Application developers can use all the logical names from the stack template to interact with the services. In the example below, the database resource is configured using a CloudFormation template, defining a logical name for the database instance.

"applicationDatabase": {
  "Type": "AWS::RDS::DBInstance",
  "Properties": {
  	"AllocatedStorage": "5",
  	"DBInstanceClass": "db.t1.micro",
  	"DBName": "test"
  	...
  ]
 }
}

The datasource is then created and will receive a physical name (e.g. ir142c39k6o5irj) as the database service name. Application developers can still use the logical name (in this case applicationDatabase) to interact with the database. The example below shows the stack configuration which is defined by the element aws-context:stack-configuration and resolves automatically the particular stack. The data-source element uses the logical name for the db-instance-identifier attribute to work with the database.

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:aws-context="http://www.springframework.org/schema/cloud/aws/context"
	   xmlns="http://www.springframework.org/schema/beans"
	   xsi:schemaLocation="http://www.springframework.org/schema/cloud/aws/context
	   http://www.springframework.org/schema/cloud/aws/context/spring-cloud-aws-context.xsd">

  <aws-context:context-credentials>
  	...
  </aws-context:context-credentials>

  <aws-context:context-region .. />

  <aws-context:stack-configuration/>

  <jdbc:data-source db-instance-identifier="applicationDatabase" ... />
</beans>
[Tip]Tip

Further detailed information on the Amazon RDS configuration and setup can be found in the respective chapter in this documentation.

4.2 Manual CloudFormation configuration

If the application is not running inside a stack configured EC2 instance, then the stack configuration must be configured manually. The configuration consists of an additional element attribute stack-name that will be used to resolve all the respective stack configuration information at runtime.

<beans ....>
	...
  <aws-context:stack-configuration stack-name="myStackName" />
    ...
</beans>

4.3 CloudFormation configuration with Java config classes

Spring Cloud AWS also supports the configuration of the CloudFormation support within Java classes avoiding the use of XML inside the application configuration. Spring Cloud AWS provides the annotation og.springframework.cloud.aws.context.config.annotation.EnableStackConfiguration that allows the automatic and manual stack configuration. The next example shows a configuration class that configures the CloudFormation support with an explicit stack name (here manualStackName).

@Configuration
@EnableStackConfiguration(stackName = "manualStackName")
class ApplicationConfiguration {
}
[Tip]Tip

Do not define the stackName attribute if an automatic stack name should be enabled.

4.4 CloudFormation configuration in Spring Boot

Spring Cloud AWS also supports the configuration of the CloudFormation support within the Spring Boot configuration. The manual and automatic stack configuration can be defined with properties that are described in the table below.

propertyexampledescription

cloud.aws.stack.name

myStackName

The name of the manually configured stack name that will be used to retrieve the resources.

cloud.aws.stack.auto

true

Enables the automatic stack name detection for the application.

4.5 Manual name resolution

Spring Cloud AWS uses the CloudFormation stack to resolve all resources internally using the logical names. In some circumstances it might be needed to resolve the physical name inside the application code. Spring Cloud AWS provides a pre-configured service to resolve the physical stack name based on the logical name. The sample shows a manual stack resource resolution.

@Service
public class ApplicationService {

 private final ResourceIdResolver resourceIdResolver;

 @Autowired
 public ApplicationService(ResourceIdResolver resourceIdResolver) {
 	this.resourceIdResolver = resourceIdResolver;
 }

 public void handleApplicationLogic() {
 	String physicalBucketName =
 		this.resourceIdResolver.resolveToPhysicalResourceId("someLogicalName");
 }
}

4.6 Stack Tags

Like for the Amazon EC2 instances, CloudFormation also provides stack specific tags that can be used to configure stack specific configuration information and receive them inside the application. This can for example be a stage specific configuration property (like DEV, INT, PRD).

<beans ....>
	...
	<aws-context:stack-configuration user-tags-map="stackTags"/>
	...
</beans>

The application can then access the stack tags with an expression like #{stackTags.key1}.

4.7 Using custom CloudFormation client

Like for the EC2 configuration setup, the aws-context:stack-configuration element supports a custom CloudFormation client with a special setup. The client itself can be configured using the amazon-cloud-formation attribute as shown in the example:

<beans>
	<aws-context:stack-configuration amazon-cloud-formation=""/>

	<bean class="com.amazonaws.services.cloudformation.AmazonCloudFormationClient">
	</bean>
</beans>