== 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 https://aws.amazon.com/cloudformation/[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.

image::cloudformation-overview.png[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.

=== Dependencies

To enable CloudFormation support in Spring Cloud AWS you must add following dependency that will trigger `ContextStackAutoConfiguration`:

[source,xml,indent=0]
----
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-cloudformation</artifactId>
</dependency>
----

=== 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.

[source,xml,indent=0]
----
"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.

[source,xml,indent=0]
----
<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]
====
Further detailed information on the Amazon RDS configuration and setup can be found in the respective chapter in this
documentation.
====


=== 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.

[source,xml,indent=0]
----
<beans ....>
	...
  <aws-context:stack-configuration stack-name="myStackName" />
    ...
</beans>
----

=== 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`).

[source,java,indent=0]
----
@Configuration
@EnableStackConfiguration(stackName = "manualStackName")
class ApplicationConfiguration {
}
----

[TIP]
====
Do not define the `stackName` attribute if an automatic stack name should be enabled.
====

=== 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.

[cols="3*", options="header"]
|===
|property
|example
|description

|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.

|===


=== 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.

[source,java,indent=0]
----
@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");
 }
}
----

=== 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).

[source,xml,indent=0]
----
<beans ....>
	...
	<aws-context:stack-configuration user-tags-map="stackTags"/>
	...
</beans>
----

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

=== 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:

[source,xml,indent=0]
----
<beans>
	<aws-context:stack-configuration amazon-cloud-formation=""/>

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