Create AWS cache clusters in VPC with CloudFormation - amazon-web-services

I am creating an AWS stack inside a VPC using CloudFormation and need to create ElastiCache clusters on it. I have investigated and there is no support in CloudFormation to create cache clusters in VPCs.
Our "workaround" was to to create the cache cluster when some "fixed" instance (like a bastion for example) bootstrap using CloudInit and AWS AmazonElastiCacheCli tools (elasticache-create-cache-subnet-group, elasticache-create-cache-cluster). Then, when front end machines bootstrap (we are using autoscaling), they use elasticache-describe-cache-clusters to get cache cluster nodes and update configuration.
I would like to know if you have different solutions to this problem.

VPC support has now been added for Elasticache in Cloudformation Templates.
To launch a AWS::ElastiCache::CacheCluster in your VPC, create a AWS::ElastiCache::SubnetGroup that defines which subnet in your VPC you want Elasticache and assign it to the CacheSubnetGroupName property of AWS::ElastiCache::CacheCluster.

You workaround is a reasonable one (and shows that you seem to be in control of your AWS operations already).
You could improve on your custom solution eventually by means of the dedicated CustomResource type, which are special AWS CloudFormation resources that provide a way for a template developer to include resources in an AWS CloudFormation stack that are provided by a source other than Amazon Web Services. - the AWS CloudFormation Custom Resource Walkthrough provides a good overview of what this is all about, how it works and what's required to implement your own.
The benefit of using this facade for a custom resource (i.e. the Amazon ElastiCache cluster in your case) is that its entire lifecycle (create/update/delete) can be handled in a similar and controlled fashion just like any officially supported CloudFormation resource types, e.g. resource creation failures would be handled transparently from the perspective of the entire stack.
However, for the use case at hand you might actually just want to wait for official support becoming available:
AWS has announced VPC support for ElastiCache in the context of the recent major Amazon EC2 Update - Virtual Private Clouds for Everyone!, which boils down to Default VPCs for (Almost) Everyone.
We want every EC2 user to be able to benefit from the advanced networking and other features of Amazon VPC that I outlined above. To enable this, starting soon, instances for new AWS customers (and existing customers launching in new Regions) will be launched into the "EC2-VPC" platform. [...]
You don’t need to create a VPC beforehand - simply launch EC2
instances or provision Elastic Load Balancers, RDS databases, or
ElastiCache clusters like you would in EC2-Classic and we’ll create a
VPC for you at no extra charge. We’ll launch your resources into that
VPC [...] [emphasis mine]
This update sort of implies that any new services will likely be also available in VPC right away going forward (else the new EC2-VPC platform wouldn't work automatically for new customers as envisioned).
Accordingly I'd expect the CloudFormation team to follow suit and complete/amend their support for deployment to VPC going forward as well.

My solution for this has been to have a controller process that polls a message queue, which is subscribed to the SNS topic which I notify CloudFormation events to (click advanced in the console when you create a CloudFormation stack to send notifications to an SNS Topic).
I pass the required parameters as tags to AWS::EC2::Subnet and have the controller pick them up, when the subnet is created. I execute the set up when a AWS::CloudFormation::WaitConditionHandle is created, and use the PhysicalResourceId to cURL with PUT to satisfy a AWS::CloudFormation::WaitCondition.
It works somewhat, but doesn't handle resource deletion in ElastiCache, because there is no AWS::CloudFormation::WaitCondition analogue for stack deletion. That's a manual operation procedure wth my approach.
The CustomResource approach looks more polished, but requires an endpoint, which I don't have. If you can put together an endpoint, that looks like the way to go.

Related

Retrieve existing resource data using AWS Cloudformation

I need to retrieve existing data/properties of a given resource by using an AWS Cloudformation template. Is it possible? If it is how can I do it?
Example 1:
Output: Security Group ID which allows traffic on port 22
Example 2:
Output: Instance ID which use default VPC
AWS CloudFormation is used to deploy infrastructure from a template in a repeatable manner. It cannot provide information on any resources created by any methods outside of CloudFormation.
Your requirements seem more relevant to AWS Config:
AWS Config provides a detailed view of the configuration of AWS resources in your AWS account. This includes how the resources are related to one another and how they were configured in the past so that you can see how the configurations and relationships change over time.
An AWS resource is an entity you can work with in AWS, such as an Amazon Elastic Compute Cloud (EC2) instance, an Amazon Elastic Block Store (EBS) volume, a security group, or an Amazon Virtual Private Cloud (VPC).
Using your examples, AWS Config can list EC2 instances and any resources that are connected to the instances, such as Security Groups and VPCs. You can easily click-through these relationship and view the configurations. It is also possible to view how these configurations have changed over time, such as:
When EC2 instance changed state (eg stopped, running)
When rules changed on Security Groups
Alternatively, you can simply make API calls to AWS services to obtain the current configuration of resources, such as calling DescribeInstances to obtain a list of Amazon EC2 instances and their configurations.

how to list all the NAT Gateway in a VPC via CDK?

In CDK, i see that NAT gateways are represented as CfnNatGateway. I am just whether there is any way to list all the CfnNatGateway.
My purpose is to whitelist the elastic ips of those NAT gateways through CDK.
You could use a Custom Resource, which perform "arbitrary lookups or modifications during a CloudFormation deployment." A Custom Resource is in essence a Lambda that is called during the stack deployments, which you would use to call DescribeNatGateway API, extract the IPs and output the result.
Whether you should do this is a different question. Using a Custom Resource to lookup IPs introduces deploy-time side-effects. Instead, the CDK best practice is deterministic deploys:
Determinism is key to successful AWS CDK deployments. A AWS CDK app should have essentially the same result whenever it is deployed to a given environment.
The CDK would have you lookup the IPs at synth-time:
Since your AWS CDK app is written in a general-purpose programming language, it can execute arbitrary code, use arbitrary libraries, and make arbitrary network calls. For example, you could use an AWS SDK to retrieve some information from your AWS account while synthesizing your app...

Attach Capacity Provider to a ECS Cluster created in different Cloudformation stacks

My team's current task is to develop an ECS Cluster to be able to migrate from Elastic Beanstalk.
Since we have our entire infrastructure in Cloudformation we had to stich this implementation to our current templates.
The idea is to have the cluster created separately with the underlying infrastructure that will be shared between the services that will eventually be deployed to the cluster.
There is a different template for the empty ECS Cluster and another for the Services (and all resources specific to Services).
The capacity providers are created with (and attached to) the services. From what I could find there is no way in Cloudformation to make a capacity provider appear as part of the cluster after the cluster is created. The capacity provider appears on the Services but not on the cluster and the Service ends up with no resources to provision its tasks.
The workaround I have right now is to define a lambda as a custom resource to call the putClusterCapacityProvider action, and pass an empty array to the defaultCapacityProviderStrategy property.
This strategy is working but feels a little too hacky. Am I missing something? Is there another way to have the capacity providers appear on the cluster after the cluster is created?
CloudFormation has been updated to enable Capacity Provider tuning on existing Clusters via AWS::ECS::ClusterCapacityProviderAssociations.
See https://aws.amazon.com/blogs/containers/managing-compute-for-amazon-ecs-clusters-with-capacity-providers/ for details

AWS equivalent for Azure Resourcegroup

Azure Resource group is one thing which ties one complete stack together, so in case you want to know what your complete stack looks like just open up your RG and all resources are there(not talking about very big stacks ).
Do we have any service in AWS like this ??
AWS also has Resource Groups. It's not identical to Azure resource groups. But it will work for your need. You need to use tags for the resources and then group them using AWS Resource Groups. Tags are very powerful and widely used in AWS.
An AWS Cloudformation template creates a "Stack" with all the resources defined in the template. In the AWS console what you see under the Cloudformation service are these stacks. They seem to me to be very much like an Azure Resource Group. The life cycle of the resources in the template are managed by the stack. If you delete the stack all the resources are deleted; very much like an Azure Resource Group.
As mentioned in comments you can group together AWS resources using resource groups. If you are looking for more than mere grouping then there is AWS OpsWorks Stacks. AWS OpsWorks Stacks is nothing but chef under the hood. Here you can get the full view of associated resources and you can manage as well.
I've been playing in Azure for a while with Kubernetes (AKS) and Terraform. I was used to deploying an Azure resource group and everything in it:
Key vault
storage account
DataBricks
Data Factory
SQL Server (or some other database)
Simple enough. So, I just tried to deploy a similar data stack in AWS. It's not at all the same, and a lot more effort.
The VPC seems to be the first place to start. You'll also have to
think about CIDR addresses too.
Subnets (you'll be defining CIDR blocks here too) and deciding availability zones come next.
You'll need security group
You'll also need IAM resources and to attach the relevant roles/policies. In Azure, once permissions and Service Principals are in place, you don't have to worry about these things.
All this is before you've deployed anything.
Now that's my immediate feeling trying to replicate what I was doing on Azure. I didn't let how long it takes to deploy these resources on AWS (in the EU region - YMMV) compared to Azure 🙄 cloud my judgement either...
A Cloudformation 'stack' was created when I tested using the AWS EKSCLI command line tool to provision a kubernetes cluster and nodes. Deleting a stack on Cloudformation will remove all the associated resources, like if you were to remove a resource group on Azure.
I think using Terraform is probably a good idea, which is the conclusion you may arrive at after having to chase down why you can't delete a certain resource because something is still using it (and it's not all in the same place (resource group) like in Azure.

AWS OpsWorks vs CloudFormation

I want to understand the exact limitations of OpsWorks- things that we simply may not be able to do or not optimally. That would require to go to the next level - CloudFormation. Of course we can use OpsWorks + CloudFormation - get best of both worlds - a best practice.
Some limitations of OpsWorks that I am aware of are - it cant provision everything - like EMR, S3 etc - but have never found on exhaustive list. Also OpsWorks the AutoScaling configuration has limitations. And CloudFormation lets us version control the environment unlike OpsWorks. Do understand that there is good amount of overlap and CloudFormation does add to complexity.
There was a previous discussion but the demarcations were not made clear.
OpsWorks is a totally different service from CloudFormation.
OpsWorks is focused at managing applications layered as stacks, and taking advantadge of chef recipes for setting up and deploying applications.
CloudFormation is a descriptive language to create sets of AWS infrastructure.
It may look obvious, but the thing is that whenever you prefer to manage an application and its deployment cycle, the OpsWorks service is better suited. You can of course use cloud formation to define entire applications and layers in OpsWorks and that will allow you to replicate entire applications layer sets (for test environments and so)
The only good way to learn the boundaries of every service is using them for your needs, then you will find where Opsworks is strong and where Cloudformation complements or allows you to automate your Opsworks setups.
About versioning, CF lets you version the infrastructure stack, which may have nothing to do with the version of code that you are managing through opsworks.
regards
In many cases CloudFormation is used with OpsWorks; where CloudFormation is used to provision the infrastructure and OpsWorks to configure the resources created. OpsWorks (via Chef or Puppet) provides a richer set of abilities when it comes to configuring the application stack then the simple shell scripting offered by CloudFormation. So, generally CloudFormation is used to deploy AWS resources, and OpsWorks is used to do the detailed configuration of the application(s)/operating system(s).
In some ways one can say that CloudFormation is focused more with a collection of AWS infrastructure resources rather than the application itself; but as you have alluded to some things can be done by both services interchangeably.
This AWS link may help where it states:
“Compared to AWS CloudFormation, AWS OpsWorks Stacks supports a narrower range of application-oriented AWS resource types including Amazon EC2 instances, Amazon EBS volumes, Elastic IPs, and Amazon CloudWatch metrics.”
and this is certainly not a limitation for CloudFormation.