How to create a CloudFormation template for MySQL? - mysql

How to create CloudFormation template for setting up WordPress on one instance and MySQL on another EC2 instance?
I used this part for MySQL, but doesn't work, please give a suggestion... thank you.
"DatabaseServer" : {
"Type": "AWS::EC2::Instance",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"config" : {
"packages" : {
"yum" : {
"mysql" : [],
"mysql-server" : [],
"mysql-devel" : [],
"mysql-libs" : []
}
}
},
"services" : {
"sysvinit" : {
"mysqld" : { "enabled" : "true", "ensureRunning" : "true" }
}
}
}
},

AWS CloudFormation offers a large list or sample AWS CloudFormation Templates, which you can start/test easily from the AWS Management Console. There are several MySQL based solutions available, including a dedicated one for WordPress as well as a generic LAMP stack, in particular:
WordPress is web software you can use to create a beautiful website or blog.
Single EC2 Instance with local MySQL database
wordpress-via-cfn-bootstrap.template - one EC2 instance and one RDS instance
Several others for usage with an SCM solution like Chef/Puppet/...
A simple LAMP stack running a PHP "Hello World" application.
Single EC2 Instance with local MySQL database
Single EC2 Instance web server with Amazon RDS database instance
Highly Available Web Server with Multi-AZ Amazon RDS Instance
I recommend to explore the selected template(s) and continue from there by tailoring it to your needs, e.g. by splitting the single EC2 instance into two (though I'd highly recommend to use a solution based on an Amazon RDS for MySQL database instead, which is much more robust and easier to handle for starters, for only slightly increased cost).

To create a MySQL RDS instance with CFN you need to use the resource AWS::RDS::DBInstance with mysql engine and the wanted EngineVersion. There are some others props that you need to initialize that are not specific for MySQL Instance.
You can use Altostra Designer to create the CFN template super quick.

Related

ECS EC2 Launch Type: Service database connection string

I am trying out a small POC (learning experiment) on docker. I have 3 docker images, one each for a storefront, a search engine and a database engine called, storefront, solr, docmysql respectively. I have tried running them in a docker swarm (on a single node) on ec2 and it works fine.
In the POC, I next needed to move this to AWS ECS using the EC2 launch type on a single Non-Amazon ECS-Optimized AMI. I have installed and started a ecs-agent on this. I have created 3 services with one task for each of the 3 images configured as containers within the task. The question is about connecting to the database from the storefront.
The storefront has a property file where the database connection is typically defined as
"jdbc:mysql://docmysql/hybris64?useConfigs=maxPerformance&characterEncoding=utf8&useSSL=false".
This worked when I ran it as a docker swarm. Once I moved it to ECS (EC2 launch type), I had to expose the port 3306 from my task/container for the docmysql service. This gave me a service endpoint of docmysql.local, with 'local' being a private namespace. I tried changing the connection string to
"jdbc:mysql://docmysql.local/hybris64?useConfigs=maxPerformance&characterEncoding=utf8&useSSL=false"
in the property file and it always fails with " Name or service not known". What should my connection string be? When the service is created I see 2 entries in Route 53, one SRV record and a A record. The A record has as its name a .docmysql.local, If I use this in the database connection string, I see that it works but obvious not the right thing to do with the hadcoded taskid. I have read about AWS Cloud Map (servicediscovery) but still not very clear how to go about it. I will not be putting any loadbalancer in front of my DB task in the service, there will always be only one task for the db.
So what is the best way to generate the connection string that works. Also why did I not have issues when I ran it as a docker swarm.
I know I can use an RDS instead of stating my own database, I will try that but for now need this working as I have started with this. Thanks for any help.
Well, I've raised some points before my own solution within the problem:
Do you need your instance to scale using ECS? If not, migrate it to RDS.
Do you need to deploy it on EC2-Type? If not, use fargate, it is more simple to handle.
Now, I've faced that issue on Fargate, and discovered that depending on your container/task definitions, it can be used inside the same task for testing purposes, so, 127.0.0.1 should be the answer.
On different tasks you need to work with awsvpc network mode so, you will have this:
Each task that uses the awsvpc network mode receives its own elastic network interface, which is attached to the container instance that hosts it. (FROM AWS)
My suggestion is to create a Lambda Function to discover your network interface dynamically.
Read this for deeply understanding:
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking.html
https://aws.amazon.com/blogs/developer/invoking-aws-lambda-functions-from-java/

deployment manager Cloud SQL

I am trying to create CloudSQL Instance with Failover Replica using Deployment Manager.
I am able to create a Read Replica but couldn't create Failover Replica.
Can you please provide me a Deployment Manager Script or suggest me with the changes to the code below:
https://github.com/GoogleCloudPlatform/deploymentmanager-samples/tree/master/examples/v2/sqladmin/jinja
Thanks
Here you have a tutorial on how to create a CloudSQL database with high availability (Master + Failover replica).
For this purpose the Deployment Manager doesn't really make a difference. I will go on how to create the database and replica with the gcloud SDK, if you want to use the console it's explained on the link I provided.
Create the database and replica from the Cloud Shell with this command:
gcloud sql instances create [MASTER INSTANCE NAME] --enable-bin-log --backup-start-time=00:01 --failover-replica-name=[FAILOVER INSTANCE NAME]
Check the rest of the options for gcloud sql instances create here. You need the flags --enable-bin-log enabled for this, and as you have binary logs you need to enable the backups. The "backup-start-time=" is in UTC time.
NOW, the main issue you are facing is that you want to modify that template to deploy a master and failover replica, but the template is deploying a FIRST GENERATION instance (see the "replicationType: SYNCHRONOUS" value), and the failover replica is limited to SECOND GENERATION instances.
The API request for what you are trying to accomplish would go something like this:
{
"name": "master-db",
"settings": {
"tier": "db-n1-standard-1",
"backupConfiguration": {
"binaryLogEnabled": true,
"startTime": "00:01",
"enabled": true
}
},
"failoverReplica": {
"name": "failover-db"
}
}
Check the sqladmin API explorer page to explore the different possible values easily. Afterwards converting the calls to a jinja template should be easy.

External hive metastore for EMR

I am creating a EMR cluster with default hive meta store , after which i am overriding the hive-site.xml with some property which are pointing the aws rds instance as hive metastore , everything is fine , but after restarting the hive server , i am not able to use RDS as hive metastore. It is still usin the default hive metastore created by EMR.
You can override the default configurations for applications by supplying a configuration object for applications when you create a cluster. The configuration object is referenced as a JSON file. Configuration objects consist of a classification, properties, and optional nested configurations. Properties are the settings you want to change in that file. You can specify multiple classifications for multiple applications in a single JSON object.
For overriding hive-site.xml with your external mysql metastore information, create a configuration file called hiveConfiguration.json containing edits to hive-site.xml:
[
{
"Classification": "hive-site",
"Properties": {
"javax.jdo.option.ConnectionURL": "jdbc:mysql:\/\/hostname:3306\/hive?createDatabaseIfNotExist=true",
"javax.jdo.option.ConnectionDriverName": "org.mariadb.jdbc.Driver",
"javax.jdo.option.ConnectionUserName": "username",
"javax.jdo.option.ConnectionPassword": "password"
}
}
]
Use hiveConfiguration.json with the following AWS CLI command to create the cluster:
aws emr create-cluster --release-label emr-5.11.0 --instance-type m3.xlarge --instance-count 2 \
--applications Name=Hive --configurations ./hiveConfiguration.json --use-default-roles
Reference :
https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-hive-metastore-external.html
Why do you restart Hive-server2 ? If you are changing properties like hive.metastore.* , then you will need to restart Hive Metastore daemon instead, which on EMR is part of Hcatalog. Actually, you might not need to even restart anything for just updating the metastore DB. You can just run offline schematool -initSchema to point to the new DB.
see https://cwiki.apache.org/confluence/display/Hive/Hive+Schema+Tool

Template error when mounting EFS to Elastic Beanstalk EC2 using AWS mount script

I am running into
"Service:AmazonCloudFormation, Message:Template error: every Fn::Join object requires two parameters, (1) a string delimiter and (2) a list of strings to be joined or a function that returns a list of strings (such as Fn::GetAZs) to be joined."
error when trying to deploy tomcat application with
https://github.com/awslabs/elastic-beanstalk-docs/blob/master/configuration-files/aws-provided/instance-configuration/storage-efs-mountfilesystem.config
script to mount the EFS file system to the elastic beanstalk EC2 instance.
I have been trying for a while now to resolve it. Any help is highly appreciated.
The EFS and EC2 are on the same VPC and mounting successfully works when I SSH into the EC2.
Surprisingly I dont see any ERROR logs in the CloudFormation stack either.
I finally figured out the problem. Its a very stupid mistake, in case you run into this problem here's what i was doing
The discreption says "To use this file to mount a file system that you created outside of AWS Elastic Beanstalk, replace the Ref with the resource ID" in below line
FILE_SYSTEM_ID: '{"Ref" : "FileSystem"}' so i inferred it should be
FILE_SYSTEM_ID: '{"<RESOURCE_ID>" : "FileSystem"}' no this is wrong what they actually mean is do this
FILE_SYSTEM_ID: RESOURCE_ID
I know this was stupid error but in case someone's stuck like me. Hopefully you don't do this mistake.

How to choose the EC2 Instance type of an Elastic Beanstalk environment when creating it using awscli?

I've been through all the documentation (I guess). And haven't found a way, yet, to choose which EC2 instance type to use for my environment.
You can specify it when you create your environment. (It will overwrite what you selected when you did eb init)
eb create --instance_type t2.micro
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb3-create.html
You can also set it in your .ebextensions/config
option_settings:
aws:autoscaling:launchconfiguration:
InstanceType: t2.micro
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options.html