Skip to content

Instantly share code, notes, and snippets.

@mark-schaal
Created July 27, 2017 16:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mark-schaal/ddb3fddae624423d9e3abe679e753671 to your computer and use it in GitHub Desktop.
Save mark-schaal/ddb3fddae624423d9e3abe679e753671 to your computer and use it in GitHub Desktop.
"rEC2InstanceAtlassianConfluence": {
"Type": "AWS::EC2::Instance",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"configSets" : {
"bootstrap" : [
"security-updates",
"perl-installation",
"psql-tools-installation",
"mount-ebs",
"confluence-installation",
"confluence-modify-serverXML",
"cloudwatch-monitoring-init"
]
},
"security-updates" : {
"commands":{
"0-write-test-file" : {
"command": "touch ~/security-updates.txt"
},
"1-yum-updates": {
"command": "sudo yum -y update"
}
}
},
"perl-installation" : {
"packages": {
"yum": {
"perl-Switch" : [],
"perl-DateTime" : [],
"perl-Sys-Syslog" : [],
"perl-LWP-Protocol-https" : []
}
}
},
"psql-tools-installation" : {
"packages" : {
"yum" : {
"postgresql95" : [],
"postgresql95-devel" : [],
"postgresql95-libs" : []
}
}
},
"mount-ebs": {
"commands": {
"mount1": {
"command": "mkfs -t ext4 /dev/xvdf"
},
"mount2": {
"command": "mkdir /atlassian"
},
"mount3": {
"command": "mount /dev/xvdf /atlassian"
},
"mount4": {
"command": "echo \"/dev/xvdf /atlassian ext4 defaults,nofail 0 2\" >> /etc/fstab"
}
}
},
"confluence-installation" : {
"packages" : {
"yum" : {
"tomcat-native" : []
}
},
"groups" : {},
"users" : {},
"sources" : {},
"files": {
"/tmp/response.varfile": {
"content": { "Fn::Join" : ["",[
"#install4j response file for Confluence 6.0.3\n",
"launch.application$Boolean=true\n",
"rmiPort$Long=8000\n",
"app.install.service$Boolean=true\n",
"existingInstallationDir=/opt/Confluence\n",
"sys.confirmedUpdateInstallationString=false\n",
"sys.languageId=en\n",
"sys.installationDir=/opt/atlassian/confluence\n",
"app.confHome=/atlassian/application-data/confluence\n",
"executeLauncherAction$Boolean=true\n",
"httpPort$Long=8090\n",
"portChoice=default\n"
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
}
},
"commands" : {
"0-write-test-file":{
"command": "touch ~/confluence-6.0.3-download.txt"
},
"1-download-confluence-6.0.3":{
"command": "sudo wget https://www.atlassian.com/software/confluence/downloads/binary/atlassian-confluence-6.0.3-x64.bin",
"cwd": "/tmp"
},
"2-make-confluence-6.0.3-executable":{
"command": "sudo chmod a+x atlassian-confluence-6.0.3-x64.bin",
"cwd": "/tmp"
},
"3-install-confluence-6.0.3":{
"command": "sudo ./atlassian-confluence-6.0.3-x64.bin -q -varfile response.varfile",
"cwd": "/tmp"
}
},
"service":{}
},
"confluence-modify-serverXML": {
"packages" : {
"yum" : {
"xmlstarlet" : []
}
},
"commands": {
"modifyConf1": {
"command": "xmlstarlet ed --inplace --insert \"/Server/Service/Connector\" --type attr -n scheme -v https /opt/atlassian/confluence/server.xml"
},
"modifyConf2": {
"command": "xmlstarlet ed --inplace --insert \"/Server/Service/Connector\" --type attr -n proxyPort -v 443 /opt/atlassian/confluence/server.xml"
},
"modifyConf3": {
"command": "xmlstarlet ed --inplace --insert \"/Server/Service/Connector\" --type attr -n secure -v true /opt/atlassian/confluence/server.xml"
},
"modifyConf4": {
"command": "service confluence restart"
}
}
},
"cloudwatch-monitoring-init" : {
"commands": {
"0-CloudWatchScriptDownload": {
"command": "wget -O /tmp/cloudwatch-monitoring.zip https://ec2-downloads.s3.amazonaws.com/cloudwatch-samples/CloudWatchMonitoringScripts-v1.1.0.zip"
},
"1-CloudWatchScriptExtration": {
"command": "unzip /tmp/cloudwatch-monitoring.zip -d /tmp/"
},
"2-CronPatternDefinition": {
"command": "echo '*/5 * * * * /tmp/aws-scripts-mon/mon-put-instance-data.pl --mem-used --mem-avail --swap-used --disk-space-util --disk-space-used --disk-space-avail --disk-path=/ --disk-path=/atlassian' >>/etc/cron.cloudwatch"
},
"3-CronTabIntegration": {
"command": "crontab /etc/cron.cloudwatch"
}
}
}
}
},
"Properties": {
"BlockDeviceMappings": [
{
"DeviceName": "/dev/sdf",
"Ebs": {
"VolumeSize": "250"
},
"VirtualName": "Atlassian Confluence App Data"
}
],
"IamInstanceProfile": { "Ref": "pIAMInstanceProfile" },
"ImageId": {
"Ref": "pEC2ServerAMI"
},
"InstanceInitiatedShutdownBehavior": "stop",
"InstanceType": {
"Ref": "pEC2InstanceType"
},
"KeyName":{
"Ref": "pEC2Keypair"
},
"Monitoring": true,
"SubnetId": {
"Ref": "pEC2SubnetTarget"
},
"SecurityGroupIds": [
{
"Ref": "pEC2SecurityGroupBastionHost"
},
{
"Ref": "pEC2SecurityGroupAtlassianInstanceDefault"
}
],
"Tags": [
{
"Key": "Name",
"Value": {
"Ref": "pApplicationName"
}
},
{
"Key": "Environment",
"Value": {
"Ref": "pEnvironment"
}
},
{
"Key": "Product Owner",
"Value": {
"Ref": "pTagProductOwner"
}
},
{
"Key": "System Owner",
"Value": {
"Ref": "pTagSystemOwner"
}
}
],
"UserData" : { "Fn::Base64" :
{ "Fn::Join" : ["", [
"#!/bin/bash -xe\n",
"# Version 1.0\n",
"# Update AWS CFN Bootstrap \n",
"yum update -y aws-cfn-bootstrap\n",
"# Install the files and packages from the metadata\n",
"/opt/aws/bin/cfn-init -v ",
" --stack ", { "Ref" : "AWS::StackName" },
" --resource rEC2InstanceAtlassianConfluence ",
" --configsets bootstrap ",
" --region ", { "Ref" : "AWS::Region" }, "\n"
]]}
}
}
}
@antaltshul
Copy link

antaltshul commented Jul 27, 2017

Nested Joins (readability/clarity)

!Join
  - '\n'
  - - '#!/bin/bash -xe'
    - '# Version 1.0'
    - '# Update AWS CFN Bootstrap'
    - 'yum update -y aws-cfn-bootstrap'
    - '# Install the files and packages from the metadata'
    - !Join
      - ' '
      - - '/opt/aws/bin/cfn-init -v'
        - '         --stack'
        - !Ref AWS::StackName
        - '         --resource'
        - 'rEC2InstanceAtlassianConfluence'
        - '         --configsets'
        - 'bootstrap'
        - '         --region'
        - !Ref AWS::Region
    - ''

I took some liberties with the formatting of the second join since the goal was readability. Those lines can be combined by manually adding spaces and joining with an empty delimiter, and can be further compressed into one line with a '!Sub'. This just seemed like the most natural flow. However, due to needing to preserve the terminating \n (is this really necessary? But, assuming it is...), this may be less attractive.

JSON-like Most-close preservation of source JSON presentation

!Join
  - ''
  - - '#!/bin/bash -xe\n'
    - '# Version 1.0\n'
    - '# Update AWS CFN Bootstrap\n'
    - 'yum update -y aws-cfn-bootstrap\n'
    - '# Install the files and packages from the metadata\n'
    - '/opt/aws/bin/cfn-init -v'
    - '--stack' 
    - !Ref ${AWS::StackName}
    - '--resource rEC2InstanceAtlassianConfluence'
    - '--configsets bootstrap'
    - '--region' 
    - !Ref ${AWS::Region}
    - '\n'

And with Sub

!Join
  - ''
  - - '#!/bin/bash -xe\n'
    - '# Version 1.0\n'
    - '# Update AWS CFN Bootstrap\n'
    - 'yum update -y aws-cfn-bootstrap\n'
    - '# Install the files and packages from the metadata\n'
    - !Sub '/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource rEC2InstanceAtlassianConfluence --configsets bootstrap --region ${AWS::Region}\n'

or (Sub but readability over space)

!Join
  - ''
  - - '#!/bin/bash -xe\n'
    - '# Version 1.0\n'
    - '# Update AWS CFN Bootstrap\n'
    - 'yum update -y aws-cfn-bootstrap\n'
    - '# Install the files and packages from the metadata\n'
    - !Sub '/opt/aws/bin/cfn-init -v 
      --stack ${AWS::StackName} 
      --resource rEC2InstanceAtlassianConfluence 
      --configsets bootstrap 
      --region ${AWS::Region}\n'

(if you want to preserve the multi-space stuff, would either need a block literal or all in one line)

(oh, and the quotes are in many places unnecessary, but I include them since technically with some of these special characters, if the following text ever changed to something meaningful, it would break without being quoted)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment