Install Java and Tomcat on Windows in AWS EC2 using CloudFormation

CloudFormationIt’s pretty common to see DevOps folks roll their eyes when they are asked to install Java and Tomcat on Windows Server in AWS. For some reason, folks have decided this is hard. I don’t think it’s all that hard. And I have the CloudFormation template pattern (below) to prove it. ūüôā

Here’s a description of what’s going on in this CloudFormation template snippet along with some pointers:

  • The¬†CloudFormation pattern assumes you stage the Tomcat and Java installation executables on S3 and that the template has access to the S3 bucket. You might¬†consider updating Java and Tomcat once the initial versions get old via¬†a CloudFormation change set
  • The Java and Tomcat installations are placed in the default subdirectories with default installation options on Windows Server
  • The all-important CATALINA_HOME¬†and JAVA_HOME¬†environment variables are set to the default installation directories
  • I assume you have at least PowerShell 5 installed. See this CloudFormation skeleton¬†if you need a pattern to install PowerShell 5. I actually use the code from that template pattern in every Windows Server 2012 R2 EC2 instance — and recommend you do, too
  • The PowerShell scripts that are built in a CloudFormation template can be, ahem, a bit fussy to create and execute.¬†Be certain to include a terminating semi-colon at the end of each statement. I don’t believe the ending¬†newline (\n) is absolutely required in each script. But I like it, so it stayed in during my testing. In Set-Java-Tomcat8-Paths-Homes.ps1the semicolon is required in the PowerShell script to join the old and new paths. In this case, the semicolon is not a PowerShell statement delimiter.¬†Do¬†not replace the single quotes around the semicolon in this script¬†with double quotes
  • During testing, sometimes¬†Tomcat would install as a Windows service; sometimes it wouldn’t even though the documentation says it installs by default as a service on Windows. Just be sure, I added a¬†\service.bat install statement. You’ll see an error in the cfn-init.log if Tomcat was installed as a service, but you can ignore it.

Enjoy.

   {
       "AWSTemplateFormatVersion": "2010-09-09",
       "Description": "Cloud Formation template snippet to install Java JDK and Tomcat on Windows Server 2012 R2. (c) 2017 Air11 Technology LLC -- licensed under the Apache OpenSource 2.0 license, https://opensource.org/licenses/Apache-2.0",
       "Metadata": {},
       "Parameters": {},
       "Rules": {},
       "Mappings": {},
       "Resources": {
           "JavaTomcatEC2Instance": {
               "Type": "AWS::EC2::Instance",
               "Metadata": {
                   "AWS::CloudFormation::Init": {
                       "configSets": {
                           "config": [
                               "setup"
                           ]
                       },
                       "setup": {
                           "Install-Java-Tomcat-set-env-variables-paths": {
                               "files": {
                                   "c:\\cfn\\modules\\jdk-8u121-windows-x64.exe": {
                                       "source": "https://someS3bucket.s3.amazonaws.com/jdk-8u121-windows-x64.exe"
                                   },
                                   "c:\\cfn\\modules\\apache-tomcat-8.5.11.exe": {
                                       "source": "http://someS3bucket.s3.amazonaws.com.s3.amazonaws.com/apache-tomcat-8.5.11.exe"
                                   },
                                   "c:\\cfn\\scripts\\Install-Java-JDK.ps1": {
                                       "content": {
                                           "Fn::Join": [
                                               "", [
                                                   "Set-Location C:\\cfn\\modules;",
                                                   ".\\jdk-8u121-windows-x64.exe /s ADDLOCAL=\"ToolsFeature,SourceFeature,PublicjreFeature\"",
                                                   "\n"
                                               ]
                                           ]
                                       }
                                   },
                                   "c:\\cfn\\scripts\\Install-Tomcat8.ps1": {
                                       "content": {
                                           "Fn::Join": [
                                               "", [
                                                   "Set-Location C:\\cfn\\modules;",
                                                   ".\\apache-tomcat-8.5.11.exe /S",
                                                   "\n"
                                               ]
                                           ]
                                       }
                                   },
                                   "c:\\cfn\\scripts\\Set-Java-Tomcat8-Paths-Homes.ps1": {
                                       "content": {
                                           "Fn::Join": [
                                               "", [
                                                   "$oldPath=(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment' -Name PATH).Path;",
                                                   "$addedFolder = 'C:\\Program Files\\Java\\jdk1.8.0_121\\bin; C:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\bin';",
                                                   "$newPath = $oldPath +';'+$addedFolder;",
                                                   "Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment' -Name PATH -Value $newPath ;",
                                                   "[Environment]::SetEnvironmentVariable('CATALINA_HOME', 'C:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\', 'Machine');",
                                                   "[Environment]::SetEnvironmentVariable('JAVA_HOME', 'C:\\Program Files\\Java\\jdk1.8.0_121\\', 'Machine');",
                                                   "Restart-Computer -Force;",
                                                   "\n"
                                               ]
                                           ]
                                       }
                                   },
                                   "c:\\cfn\\scripts\\Install-Tomcat8-Service.ps1": {
                                       "content": {
                                           "Fn::Join": [
                                               "", [
                                                   "Set-Location 'C:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\bin';",
                                                   ".\\service.bat install;",
                                                   "Set-Service Tomcat8 -StartupType Automatic;",
                                                   "Start-Service Tomcat8;",
                                                   "\n"
                                               ]
                                           ]
                                       }
                                   }
                               },
                               "commands": {
                                   "a-Install-Java-JDK": {
                                       "command": "powershell.exe -ExecutionPolicy RemoteSigned -Command c:\\cfn\\scripts\\Install-Java-JDK.ps1",
                                       "waitAfterCompletion": "30"
                                   },
                                   "b-Install-Tomcat8": {
                                       "command": "powershell.exe -ExecutionPolicy RemoteSigned -Command c:\\cfn\\scripts\\Install-Tomcat8.ps1",
                                       "waitAfterCompletion": "30"
                                   },
                                   "c-Set-Java-Tomcat8-Paths-Homes": {
                                       "command": "powershell.exe -ExecutionPolicy RemoteSigned -Command c:\\cfn\\scripts\\Set-Java-Tomcat8-Paths-Homes.ps1",
                                       "waitAfterCompletion": "forever"

                                   },
                                   "d-Install-Tomcat8-Service": {
                                       "command": "powershell.exe -ExecutionPolicy RemoteSigned -Command c:\\cfn\\scripts\\Install-Tomcat8-Service.ps1",
                                       "waitAfterCompletion": "30"

                                   }
                               }
                           }
                       }
                   }
               }
           }
       }
   }

 


Posted

in

,

by

Comments

5 responses to “Install Java and Tomcat on Windows in AWS EC2 using CloudFormation”

  1. Carlos Avatar
    Carlos

    LOL..I mean crumbs not “scrums”…English is not my native tongue as you can also see by my writing.

  2. Alex Neihaus Avatar
    Alex Neihaus

    Hi, Carlos.

    Thanks for the positive feedback. As you can imagine, debugging your implementation of the pattern template in this post is beyond the scope of what this blog is about. As they say, YMMV.

    Still, I’d like to help, so

    • Did you use the snippet¬†as a model in a fully-fleshed out CloudFormation template? I used ellipses (…) in the snippet to indicate where I’d removed code. I deleted the parts of the template that didn’t apply to installing Tomcat and Java via CloudFormation. IOW, this pattern or snippet, won’t run by itself.
    • My process is to edit the JSON in Visual Studio Code and then cut and paste the complete template into the CloudFormation designer. The designer has a syntax checker. Until you get “template valid”, there’s no point in trying to run the stack. It’s gonna fail.
    • I had unbalanced¬†JSON braces and brackets in the pattern. Once again, this was intended as a snippet, not as a runnable template.¬†I stripped out what I thought were¬†extraneous definitions in the snippet to more clearly show the guts of the work you need to do to install Java and Tomcat. Still, it should be valid JSON. So, I’ve updated the snippet with a syntactically valid snippet (see below; click to enlarge — it also shows you how to validate a CloudFormation template). You just have to fill in the definitions in the template that are specific to your implementation. But if you cut and paste this code snippet into the CloudFormation designer, it validates — thought it won’t work until you “finish” it with your details.

    CloudFormation snippet to install Java and Tomcat on Windows in EC2
    Thanks again and good luck.

    1. Carlos Avatar
      Carlos

      Alex, Appreciate you took the time to put an answer for me. I was able to integrate your script with my own template and do the validation.
      All I can say is that I learned more with this post that in the last week me, trying to find scrums of info along the web (I‚Äôm new to AWS as you can see ūüėČ ). Just thank you!

      1. Alex Neihaus Avatar
        Alex Neihaus

        Hi, Carlos.

        I’m glad you were successful. And I appreciate the positive feedback. CloudFormation isn’t for the faint-of-heart, is it? And AWS owes the world better tooling. Lack of tools is, IMHO, the major drawback to using CloudFormation. Need proof? The CloudFormation template snippet in this post validates but does nothing useful. Or, my favorite: CloudFormer-generated templates that do not recreate the infrastructure that they purportedly model.

        We were all AWS newbies once. I am pleased my little blog has helped you succeed in using the cloud. AWS is awesome.

  3. Carlos Avatar
    Carlos

    Alex, Thank you very much for this really useful script!! somehow I’m getting an error when the stacks run “Encountered unsupported property Install-Java-Tomcat-set-env-variables-paths”

Leave a Reply

Your email address will not be published. Required fields are marked *