AWS CloudFormation - Create Tables After RDS Instance Is Ready? - amazon-web-services

CloudFormation amateur here. Been looking online and can't find any references as to how I would go about creating my tables after my RDS instance is stood up through CloudFormation. Is it possible to specify a Lambda to launch and create all the tables, or maybe specify a SQL file to be applied? What's the standard pattern on this?

There aren't any CloudFormation resources which deal with the 'internals' of an RDS instance once it's been created; it's a black box which you're expected to configure (with users, tables and data) outside of CloudFormation. This is a bit sad, as versioning, managing and deploying database schemas is a classic deployment problem on the borderline between infrastructure and application, which is also exactly where CloudFormation sits (as a tool for versioning, managing and deploying other infrastructure).
What you could do, although it's not a beginner-level feature, is use a custom resource to connect to the RDS instance once it's created, and run appropriate SQL commands to create the users and tables. You define the schema in your CloudFormation template (either as SQL or a more structured description similar to DynamoDB AtributeDefinitions), and that schema is passed to your custom resource lambda function, which then runs the queries in the database.
If you go down this route, you'll probably do a lot of wheel-inventing of how to translate differences in the 'before' and 'after' schemas into ALTER TABLE SQL statements to fire at the database. Your custom resource lambda code needs to be very robust and always send a response back to CloudFormation, even in the case of an error. And don't forget that if your stack update fails for any reason, CloudFormation will call your custom resource again 'in reverse' (ie asking you to alter the database from the post-update schema back to the pre-update schema) as part of the rollback process.
If you do go down this road and come up with something at all robust, do publish it, because I'm sure a lot of people would be interested in it! I had a quick look online but I couldn't find anything obvious pre-existing.

Unfortunately, CF template cannot run the setup script directly. You can try, like what you have mentioned, using Lambda to run the table set up once the RDS has been created successfully by the CF template. DependsOn attribute helps. You should pass the credentials to Lambda to access the RDS.

Related

Best practices to Initialize and populate a serverless PostgreSQL RDS instance by a CloudFormation stack deployment

We are successfully spinning up an AWS CloudFormation stack that includes a serverless RDS PostgreSQL instance. Once the PostgreSQL instance is in place, we're automatically restoring a PostgreSQL database dump (in binary format) that was created using pg_dump on a local development machine on the instance PostgreSQL instance just created by CloudFormation.
We're using a Lambda function (instantiated by the CloudFormation process) that includes a build of the pg_restore executable within a Lambda layer and we've also packaged our database dump file within the Lambda.
The above approached seems complicated for something that presumably has been solved many times... but Google searches have revealed almost nothing that corresponds to our scenario. ​We may be thinking about our situation in the wrong way, so please feel free to offer a different approach (e.g., is there a CodePipeline/CodeBuild approach that would automate everything). Our preference would be to stick with the AWS toolset as much as possible.
This process will be run every time we deploy to a new environment (e.g., development, test, stage, pre-production, demonstration, alpha, beta, production, troubleshooting) potentially per release as part of our CI/CD practices.
Does anyone have advice or a blog post that illustrates another way to achieve our goal?
If you have provisioned everything via IaC (Infrastructure as Code) anyway that is most of the time-saving done and you should already be able to replicate your infrastructure to other accounts/ stacks via different roles in your AWS credentials and config files by passing the —profile some-profile flag. I would recommend AWS SAM (Serverless application model) over Cloudformation though as I find I only need to write ~1/2 the code (roles & policies are created for you mostly) and much better & faster feedback via the console. I would also recommend sam sync (it is in beta currently but worth using) so you don’t need to create a ‘change set’ on code updates, purely the code is updated so deploys take 3-4 secs. Some AWS SAM examples here, check both videos and patterns: https://serverlessland.com (official AWS site)
In terms of the restore of RDS, I’d probably create a base RDS then take a snapshot of that and restore all other RDS instances from snapshots rather than manually creating it all the time you are able to copy snapshots and in fact automate backups to snapshots cross-account (and cross-region if required) which should be a little cleaner
There is also a clean solution for replicating data instantaneously across AWS Accounts using AWS DMS (Data Migration Services) and CDC (Change Data Capture). So, process is you have a source DB and a target DB and also a 'Replication Instance' (eg EC2 Micro) that monitors your source DB and can replicate that across to different instances (so you are always in sync on data, for example if you have several devs working on separate 'stacks' to not pollute each others' logs, you can replicate data and changes out seamlessly if required from one DB) - so this works with Source DB and Destination DB both already in AWS however you can also use AWS DMS of course for local DB migration over to AWS, some more info here: https://docs.aws.amazon.com/dms/latest/sbs/chap-manageddatabases.html

Updating an Aurora serverless from MySQL 5.6 to 5.7 with CloudFormation without loss

Context
I need to upgrade a production Aurora serverless database from MySQL 5.6 to 5.7.
All my resources are deployed as Infrastructure as a Code, with CloudFormation.
Problem
Updating the engine version in the CloudFormation template would result in the database replacement, thus downtime and data loss.
I also have a lot of dependent resources that rely on the database ARN to connect. (The ARN is currently exported as a cross-stack reference).
Question
What would be a clean way to achieve that kind of maintenance, viable on the long-run ?
Thanks in advance !
If you take a look in any CloudFormation documentation each parameter will be labelled with Update requires. This will identify if there is a definitive replacement or a conditional replacement of your resource (or none at all).
For an Aurora Serverless cluster the documentation has many parameters that will force a replacement of this.
How you handle this depends on the importance of the resource, remember that even starting from a snapshot will involve potential downtime in which time any data written to the original cluster would also be lost.
Personally I would recommend looking at the following factors:
Can your system run without this database for any period of time? If no then you should run both databases simultaneously. Then use a service like DMS to synchronise between. Once you're happy perform the switchover.
Can your application run in a read-only mode? If so stop writes to the original DB and then take a snapshot. Create the new DB as an additional resource and launch from the snapshot.
I would suggest trying to create this as an additional resource, as unlike most resources losing your DB might not be as simple to rollback if it has been deleted. Once you're confident only then remove the previous DB.

Can you create AWS RDS Aurora tables using CDK?

I'm fairly new to AWS CDK, and I just created an architecture with an Aurora cluster inside of it. Is there a way to initialize a database schema inside of my CDK files? It seems a bit annoying to create the instance and then have to connect through other means in order to set up a schema. My impression of CDK is that you can do everything relating to setting up the services, so I was curious if this is a possibility.
If this isn't possible, can I use a lambda that fires off after the CDK deployment? Or maybe have a snapshot inside of s3? I'm just trying to find the best solution!
You can do this, although it requires you to execute it as a custom resource within the CDK.
You would need to create a Lambda function the performs the SQL DDL tasks for you. This would then return a successful flag back to the execution runtime to say that this "resource" was successfully created.

CloudFormation open source equivalent or rolling your own

Would anybody have any clues as to how AWS CloudFormation works under the hood?
Also, would anybody know an open-source equivalent to AWS CF (and I don't mean tooling that may be using CloudFormation)?
It's clearly a powerful orchestrator, but I'd be keen to explore the inner workings of such tools.
AWS Cloudformation has multiple pre-defined set of schemas for each of the components that are supported. When you upload a Cloudformation template for creating resources, it performs the below steps:
It validates the templates against the schema
It generates dynamic form for gathering parameters
It validates the values of parameters
Once it has all it needs, you can click Create to begin with the resource creation
Under the hood, it starts creation of resources using the internal coding for which is keeps echoing the status and progress continuously on the console.
We need to understand here that internally Cloudformation in itself is a product that does use AWS SDK/CLI as needed. However, under the hood, it maintains its own data to compare the attributes and resources when you run an update.
An open source alternative to this is Terraform. Terraform is the most widely used open source replacement of Cloudformation. Terraform is known for its Cloud independent architecture. Terraform works with multiple clouds with minimal changes in the templates.
The under-the-hood working of terraform involves creation of a State file/directory where it stores the current state of any stack identified uniquely by the name provided by the user. Terraform creates resources majorly using Python SDK (boto3) and some other APIs as needed. We need to pass the access key and secrets to the Terraform configuration in order to enable it to access the AWS Cloud environment.
If you are looking to build a smart new alternative, it should be fairly simple considering that AWS strictly follows standard design patterns in its SDK and CLI interface design. This makes it easier to convert template into executable code.
More information about working of Cloudformation can be found here

Rename ECS Service

I have a bunch of Amazon ECS services that I want to re-name. I like their task definitions, so I'm open to cloning options, I just don't see in the UpdateService API a way to rename a service. Is there an API for renaming? If not, what combination of APIs could I invoke (I figure python or awscli scripting would be the easiest option).
Considerations
I would also want to consider whether it would be possible to gracefully roll the "old name" to "new name"
Ensure security groups were applied correctly.
If possible, facilitate the mutative change via CloudFormation
I don't see any options to rename an ECS service in CLI, API, even the console. I think you're going to have to remove the service with the old name and create a new one with the new name.
There are lots of ways to make removing and creating a little easier on you:
If you are using Terraform to create and manage your ECS services, you can simply rename the service in Terraform, and it will drop and recreate the service when you apply the change.
AWS cli could certainly make this easier than doing it manually -- you could even create a wrapper script to do a rename, perhaps.
You could definitely drop and create the ECS service using Python and Boto3 (I don't use Python/Boto3 to rename services, but I do use it to drop and create services).
It's possible that CloudFormation could make this easier? I don't use CloudFormation, but since Terraform can make renaming an ECS service easier, it seems like CloudFormation might do the same.