The first article introduced AWS Cloudformation as an application management tool, while the second article discussed about launching a Cloudformation stack with an AWS Linux image.
The present article takes one step forward and introduces the various programming components of the Cloudformation template.
It also helps to create a stack which performs the below mentioned tasks:
- Create a template which will take the database password, the EC2 instance key-pair file and the instance type
- Launch an instance with the above mentioned parameters
- Install Apache , the PHP engine an MySQL in that instance
- Install a sample PHP and modify it to use with MySQL
- Create a sample DB lampdb
- Create a sample index.html file in the Apache root folder
- Test all the above mentioned resources once the stack has been created successfully
The present guide focuses on the various components of a template. Hence, it has taken the AWS LAMP template as a reference and made minor modifications to achieve the above mentioned objectives. The updated template has been attached for reference.
- AWS::CloudFormation::Init : It is used to add the metadata on the EC2 instance. The cfn-init script uses this metadata to perform its actions. The user can supply various metadata with AWS::CloudFormation::Init, such as:
- Files: This key is used to create files on the EC2-instances. The user can put the content in the template or download the content from an external URL (e.g. AWS S3). The file can have keys, such as content (content of the file), source (if the file is required to be downloaded from an external URL), group (the name of the owning group, except for Windows OS) and a few more keys.The LAMP template supplied with the present guide uses the file key as mentioned below.
"files" : { "/tmp/setup.mysql" : { "content" : "CREATE DATABASE lampdb;\n", "mode" : "000644", "owner" : "root", "group" : "root" }, "/var/www/html/index.html" : { "content" : "Hello Test This is test File ", "mode" : "000644", "owner" : "root", "group" : "root" } },
Based on the above mentioned keys, when a stack has been created, cfn-init will use the filekey from AWS::CloudFormation::Init and create one setup.mysql at /tmp/ directory and one index.html file at /var/www/html directory. - Sources: The sources are used to download an archive file and unpack it into the target directory of the EC2 instance. The present template downloads a sample PHP file supplied by the AWS LAMP stack.
"sources" : { "/var/www/html" : "https://s3.amazonaws.com/cloudformation-examples/CloudFormationPHPSample.zip" },
- Packages: This key is used to download and install the pre-packaged applications or components. E.g. with Linux the user can install packages, such as like mysql, apache and a few more. Cfn-init supports package formats, such as yum, apt, msi, python, rubygems , and rpm. The user can also specify the version of the package if required. The LAMP template uses yum and installs the mysql server, php and apache in the EC2 instance.
"packages" : { "yum" : { "mysql" : [], "mysql-server" : [], "mysql-libs" : [], "httpd" : [], "php" : [], "php-mysql" : [] } },
- Services: The services key is used to start or stop a service on instance boot. E.g. for the Linux instance, “sysvinit” is used to start or stop a service on instance boot.
"services" : { "sysvinit" : { "mysqld" : { "enabled" : "true", "ensureRunning" : "true" }, "httpd" : { "enabled" : "true", "ensureRunning" : "true" } } }
- Files: This key is used to create files on the EC2-instances. The user can put the content in the template or download the content from an external URL (e.g. AWS S3). The file can have keys, such as content (content of the file), source (if the file is required to be downloaded from an external URL), group (the name of the owning group, except for Windows OS) and a few more keys.The LAMP template supplied with the present guide uses the file key as mentioned below.
- cfn-init: This is an initialization script. It reads the metadata supplied with the AWS::CloudFormation::Init key. Based on the metadata supplied, it can install packages, write files to a disk, enable / disable or start /stop services. When the above mentioned script is used for updating any file, it will create a backup of the original file with the .bak extension.The attached template has passed parameters, such as files, services, packages, and sources, as explained above. Cfn-init will use the above mentioned metadata and install apache, php, and mysql in the EC2 instance.
"# Install LAMP packages\n", "/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, " -r WebServer ", "--region ", { "Ref" : "AWS::Region" }, " || error_exit 'Failed to run cfn-init'\n",
- AWS::CloudFormation::WaitCondition: The AWS::CloudFormation::WaitCondition and AWS::CloudFormation::WaitConditionHandle resources allow the user to put a wait condition in a template. The wait condition puts a pause on the stack creation and waits for a signal before it resumes. In the below mentioned case, Cloudformation will pause for 5 minutes after the webserver has been created.
"WaitHandle" : { "Type" : "AWS::CloudFormation::WaitConditionHandle" }, "WaitCondition" : { "Type" : "AWS::CloudFormation::WaitCondition", "DependsOn" : "WebServer", "Properties" : { "Handle" : {"Ref" : "WaitHandle"}, "Timeout" : "300" } },
The steps given below help to create a stack, as explained in creating Cloudformation stack [Link to be provided of second guide]
- Create a stack from the supplied template.
- Provide the required parameters, and tags.
- Once the instance has been launched, get the instance details and verify the groups, and keys, as configured in the template.
- Login to the instance and verify the MySQL DB using the password provided in step#2. It will also have a blank DB created, which is based on the AWS::CloudFormation::Init files and the cnf-init script.
- Verify that both index.php and index.html are a part of the apache root folder.
- Verify both the index files from the browser. It will show the output as apache, which has been installed and started as configured in the services part of AWS::CloudFormation::Init.