在 Amazon 上部署應用程式 EC2 - AWS CloudFormation

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

在 Amazon 上部署應用程式 EC2

您可以使用 CloudFormation 在 Amazon EC2執行個體上自動安裝、設定和啟動應用程式。這樣可讓您輕鬆地重複部署和更新現有安裝,無需直接連接到執行個體,為您節省了許多時間和精力。

CloudFormation 包含一組以 cfn-init為基礎的協助程式指令碼 (cfn-get-metadata、、 cfn-signalcfn-hup)cloud-init。您可以從 CloudFormation 範本中呼叫這些協助程式指令碼,以在位於相同範本的 Amazon EC2執行個體上安裝、設定和更新應用程式。

下列逐步解說說明如何建立 範本,使用協助程式指令碼來安裝、設定和啟動 ApacheSQL、My 和 來啟動LAMP堆疊PHP。您會從簡單的範本開始,設定執行 Amazon Linux 的基本 Amazon EC2執行個體,然後繼續新增至範本,直到它描述完整LAMP堆疊為止。

基本 Amazon EC2執行個體

您從定義單一 Amazon EC2執行個體的基本範本開始,其安全群組允許連接埠 22 上的SSH流量和連接埠 80 上的HTTP流量,如下列範例所示。

除了 Amazon EC2執行個體和安全群組之外,我們還建立三個輸入參數,指定執行個體類型、用於SSH存取的 Amazon EC2金鑰對,以及可用於執行個體SSH的 IP 地址範圍。映射區段可確保 CloudFormation 使用堆疊區域和 Amazon EC2執行個體類型的正確 AMI ID。最後,輸出區段URL會輸出 Web 伺服器的公有 。

注意

將 AWS Systems Manager 參數視為Mappings區段的替代方案。為了避免在每次您想要使用變更AMI的 時,使用新的 ID 更新所有範本,請在建立或更新堆疊時,使用 AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> 參數類型擷取最新的 AMI ID。Systems Manager 中AMIs也提供常用的最新版本做為公有參數。如需詳細資訊,請參閱參考現有資源和 Systems Manager 參數 CloudFormation與提供的參數類型

JSON

{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "AWS CloudFormation sample template LAMP_Single_Instance: Create a LAMP stack using a single EC2 instance and a local MySQL database for storage. This template demonstrates using the AWS CloudFormation bootstrap scripts to install the packages and files necessary to deploy the Apache web server, PHP, and MySQL at instance launch time. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template.", "Parameters" : { "KeyName": { "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instance", "Type": "AWS::EC2::KeyPair::KeyName", "ConstraintDescription" : "Can contain only ASCII characters." }, "InstanceType" : { "Description" : "WebServer EC2 instance type", "Type" : "String", "Default" : "t2.small", "AllowedValues" : [ "t1.micro", "t2.nano", "t2.micro", "t2.small", "t2.medium", "t2.large", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "g2.2xlarge", "g2.8xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "d2.xlarge", "d2.2xlarge", "d2.4xlarge", "d2.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge", "cg1.4xlarge" ], "ConstraintDescription" : "must be a valid EC2 instance type." }, "SSHLocation" : { "Description" : "The IP address range that can be used to SSH to the EC2 instances", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "0.0.0.0/0", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x" } }, "Mappings" : { "AWSInstanceType2Arch" : { "t1.micro" : { "Arch" : "HVM64" }, "t2.nano" : { "Arch" : "HVM64" }, "t2.micro" : { "Arch" : "HVM64" }, "t2.small" : { "Arch" : "HVM64" }, "t2.medium" : { "Arch" : "HVM64" }, "t2.large" : { "Arch" : "HVM64" }, "m1.small" : { "Arch" : "HVM64" }, "m1.medium" : { "Arch" : "HVM64" }, "m1.large" : { "Arch" : "HVM64" }, "m1.xlarge" : { "Arch" : "HVM64" }, "m2.xlarge" : { "Arch" : "HVM64" }, "m2.2xlarge" : { "Arch" : "HVM64" }, "m2.4xlarge" : { "Arch" : "HVM64" }, "m3.medium" : { "Arch" : "HVM64" }, "m3.large" : { "Arch" : "HVM64" }, "m3.xlarge" : { "Arch" : "HVM64" }, "m3.2xlarge" : { "Arch" : "HVM64" }, "m4.large" : { "Arch" : "HVM64" }, "m4.xlarge" : { "Arch" : "HVM64" }, "m4.2xlarge" : { "Arch" : "HVM64" }, "m4.4xlarge" : { "Arch" : "HVM64" }, "m4.10xlarge" : { "Arch" : "HVM64" }, "c1.medium" : { "Arch" : "HVM64" }, "c1.xlarge" : { "Arch" : "HVM64" }, "c3.large" : { "Arch" : "HVM64" }, "c3.xlarge" : { "Arch" : "HVM64" }, "c3.2xlarge" : { "Arch" : "HVM64" }, "c3.4xlarge" : { "Arch" : "HVM64" }, "c3.8xlarge" : { "Arch" : "HVM64" }, "c4.large" : { "Arch" : "HVM64" }, "c4.xlarge" : { "Arch" : "HVM64" }, "c4.2xlarge" : { "Arch" : "HVM64" }, "c4.4xlarge" : { "Arch" : "HVM64" }, "c4.8xlarge" : { "Arch" : "HVM64" }, "g2.2xlarge" : { "Arch" : "HVMG2" }, "g2.8xlarge" : { "Arch" : "HVMG2" }, "r3.large" : { "Arch" : "HVM64" }, "r3.xlarge" : { "Arch" : "HVM64" }, "r3.2xlarge" : { "Arch" : "HVM64" }, "r3.4xlarge" : { "Arch" : "HVM64" }, "r3.8xlarge" : { "Arch" : "HVM64" }, "i2.xlarge" : { "Arch" : "HVM64" }, "i2.2xlarge" : { "Arch" : "HVM64" }, "i2.4xlarge" : { "Arch" : "HVM64" }, "i2.8xlarge" : { "Arch" : "HVM64" }, "d2.xlarge" : { "Arch" : "HVM64" }, "d2.2xlarge" : { "Arch" : "HVM64" }, "d2.4xlarge" : { "Arch" : "HVM64" }, "d2.8xlarge" : { "Arch" : "HVM64" }, "hi1.4xlarge" : { "Arch" : "HVM64" }, "hs1.8xlarge" : { "Arch" : "HVM64" }, "cr1.8xlarge" : { "Arch" : "HVM64" }, "cc2.8xlarge" : { "Arch" : "HVM64" } }, "AWSRegionArch2AMI" : { "us-east-1" : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"}, "us-west-2" : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"}, "us-west-1" : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"}, "eu-west-1" : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"}, "eu-west-2" : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"}, "eu-west-3" : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"}, "eu-central-1" : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"}, "ap-northeast-1" : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"}, "ap-northeast-2" : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"}, "ap-northeast-3" : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"}, "ap-southeast-1" : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"}, "ap-southeast-2" : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"}, "ap-south-1" : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"}, "us-east-2" : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"}, "ca-central-1" : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"}, "sa-east-1" : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"}, "cn-north-1" : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"}, "cn-northwest-1" : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"} } }, "Resources" : { "WebServerInstance": { "Type": "AWS::EC2::Instance", "Properties": { "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, "InstanceType" : { "Ref" : "InstanceType" }, "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ], "KeyName" : { "Ref" : "KeyName" } } }, "WebServerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable HTTP access via port 80", "SecurityGroupIngress" : [ {"IpProtocol" : "tcp", "FromPort" : 80, "ToPort" : 80, "CidrIp" : "0.0.0.0/0"}, {"IpProtocol" : "tcp", "FromPort" : 22, "ToPort" : 22, "CidrIp" : { "Ref" : "SSHLocation"}} ] } } }, "Outputs" : { "WebsiteURL" : { "Description" : "URL for newly created LAMP stack", "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "WebServerInstance", "PublicDnsName" ]}]] } } } }

YAML

AWSTemplateFormatVersion: 2010-09-09 Description: >- AWS CloudFormation sample template LAMP_Single_Instance: Create a LAMP stack using a single EC2 instance and a local MySQL database for storage. This template demonstrates using the AWS CloudFormation bootstrap scripts to install the packages and files necessary to deploy the Apache web server, PHP, and MySQL at instance launch time. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template. Parameters: KeyName: Description: Name of an existing EC2 KeyPair to enable SSH access to the instance Type: 'AWS::EC2::KeyPair::KeyName' ConstraintDescription: Can contain only ASCII characters. InstanceType: Description: WebServer EC2 instance type Type: String Default: t2.small AllowedValues: - t1.micro - t2.nano - t2.micro - t2.small - t2.medium - t2.large - m1.small - m1.medium - m1.large - m1.xlarge - m2.xlarge - m2.2xlarge - m2.4xlarge - m3.medium - m3.large - m3.xlarge - m3.2xlarge - m4.large - m4.xlarge - m4.2xlarge - m4.4xlarge - m4.10xlarge - c1.medium - c1.xlarge - c3.large - c3.xlarge - c3.2xlarge - c3.4xlarge - c3.8xlarge - c4.large - c4.xlarge - c4.2xlarge - c4.4xlarge - c4.8xlarge - g2.2xlarge - g2.8xlarge - r3.large - r3.xlarge - r3.2xlarge - r3.4xlarge - r3.8xlarge - i2.xlarge - i2.2xlarge - i2.4xlarge - i2.8xlarge - d2.xlarge - d2.2xlarge - d2.4xlarge - d2.8xlarge - hi1.4xlarge - hs1.8xlarge - cr1.8xlarge - cc2.8xlarge - cg1.4xlarge ConstraintDescription: must be a valid EC2 instance type. SSHLocation: Description: The IP address range that can be used to SSH to the EC2 instances Type: String MinLength: '9' MaxLength: '18' Default: 0.0.0.0/0 AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' ConstraintDescription: Must be a valid IP CIDR range of the form x.x.x.x/x Mappings: AWSInstanceType2Arch: t1.micro: Arch: HVM64 t2.nano: Arch: HVM64 t2.micro: Arch: HVM64 t2.small: Arch: HVM64 t2.medium: Arch: HVM64 t2.large: Arch: HVM64 m1.small: Arch: HVM64 m1.medium: Arch: HVM64 m1.large: Arch: HVM64 m1.xlarge: Arch: HVM64 m2.xlarge: Arch: HVM64 m2.2xlarge: Arch: HVM64 m2.4xlarge: Arch: HVM64 m3.medium: Arch: HVM64 m3.large: Arch: HVM64 m3.xlarge: Arch: HVM64 m3.2xlarge: Arch: HVM64 m4.large: Arch: HVM64 m4.xlarge: Arch: HVM64 m4.2xlarge: Arch: HVM64 m4.4xlarge: Arch: HVM64 m4.10xlarge: Arch: HVM64 c1.medium: Arch: HVM64 c1.xlarge: Arch: HVM64 c3.large: Arch: HVM64 c3.xlarge: Arch: HVM64 c3.2xlarge: Arch: HVM64 c3.4xlarge: Arch: HVM64 c3.8xlarge: Arch: HVM64 c4.large: Arch: HVM64 c4.xlarge: Arch: HVM64 c4.2xlarge: Arch: HVM64 c4.4xlarge: Arch: HVM64 c4.8xlarge: Arch: HVM64 g2.2xlarge: Arch: HVMG2 g2.8xlarge: Arch: HVMG2 r3.large: Arch: HVM64 r3.xlarge: Arch: HVM64 r3.2xlarge: Arch: HVM64 r3.4xlarge: Arch: HVM64 r3.8xlarge: Arch: HVM64 i2.xlarge: Arch: HVM64 i2.2xlarge: Arch: HVM64 i2.4xlarge: Arch: HVM64 i2.8xlarge: Arch: HVM64 d2.xlarge: Arch: HVM64 d2.2xlarge: Arch: HVM64 d2.4xlarge: Arch: HVM64 d2.8xlarge: Arch: HVM64 hi1.4xlarge: Arch: HVM64 hs1.8xlarge: Arch: HVM64 cr1.8xlarge: Arch: HVM64 cc2.8xlarge: Arch: HVM64 AWSRegionArch2AMI: us-east-1: HVM64: ami-0ff8a91507f77f867 HVMG2: ami-0a584ac55a7631c0c us-west-2: HVM64: ami-a0cfeed8 HVMG2: ami-0e09505bc235aa82d us-west-1: HVM64: ami-0bdb828fd58c52235 HVMG2: ami-066ee5fd4a9ef77f1 eu-west-1: HVM64: ami-047bb4163c506cd98 HVMG2: ami-0a7c483d527806435 eu-west-2: HVM64: ami-f976839e HVMG2: NOT_SUPPORTED eu-west-3: HVM64: ami-0ebc281c20e89ba4b HVMG2: NOT_SUPPORTED eu-central-1: HVM64: ami-0233214e13e500f77 HVMG2: ami-06223d46a6d0661c7 ap-northeast-1: HVM64: ami-06cd52961ce9f0d85 HVMG2: ami-053cdd503598e4a9d ap-northeast-2: HVM64: ami-0a10b2721688ce9d2 HVMG2: NOT_SUPPORTED ap-northeast-3: HVM64: ami-0d98120a9fb693f07 HVMG2: NOT_SUPPORTED ap-southeast-1: HVM64: ami-08569b978cc4dfa10 HVMG2: ami-0be9df32ae9f92309 ap-southeast-2: HVM64: ami-09b42976632b27e9b HVMG2: ami-0a9ce9fecc3d1daf8 ap-south-1: HVM64: ami-0912f71e06545ad88 HVMG2: ami-097b15e89dbdcfcf4 us-east-2: HVM64: ami-0b59bfac6be064b78 HVMG2: NOT_SUPPORTED ca-central-1: HVM64: ami-0b18956f HVMG2: NOT_SUPPORTED sa-east-1: HVM64: ami-07b14488da8ea02a0 HVMG2: NOT_SUPPORTED cn-north-1: HVM64: ami-0a4eaf6c4454eda75 HVMG2: NOT_SUPPORTED cn-northwest-1: HVM64: ami-6b6a7d09 HVMG2: NOT_SUPPORTED Resources: WebServerInstance: Type: 'AWS::EC2::Instance' Properties: ImageId: !FindInMap - AWSRegionArch2AMI - !Ref 'AWS::Region' - !FindInMap - AWSInstanceType2Arch - !Ref InstanceType - Arch InstanceType: !Ref InstanceType SecurityGroups: - !Ref WebServerSecurityGroup KeyName: !Ref KeyName WebServerSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Enable HTTP access via port 80 SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref SSHLocation Outputs: WebsiteURL: Description: URL for newly created LAMP stack Value: !Join - '' - - 'http://' - !GetAtt - WebServerInstance - PublicDnsName

LAMP安裝

您將以先前的基本 Amazon EC2 範本為基礎,自動安裝 ApacheSQL、My 和 PHP。為了安裝應用程式,您將新增 UserData 屬性和 Metadata 屬性。但是,範本不會設定和啟動應用程式,直到下一個部分。

UserData 屬性會執行兩個 shell 命令:安裝 CloudFormation 協助程式指令碼,然後執行cfn-init協助程式指令碼。由於協助程式指令碼會定期更新,執行 yum install -y aws-cfn-bootstrap 命令可確保您取得最新的協助程式指令碼。當您執行 cfn-init 時,它會從 AWS::CloudFormation::Init 資源讀取中繼資料,此資料描述 cfn-init 將執行的動作。例如,您可以使用 cfn-init 和 AWS::CloudFormation::Init 來安裝套件、將檔案寫入磁碟或啟動服務。在我們的案例中,cfn-init 安裝列出的套件 (httpd、mysql 和 php) 並建立 /var/www/html/index.php 檔案 (範例PHP應用程式)。

在下列範例中,為簡潔起見,將省略標示省略符號 (...) 的部分。

JSON

{ "AWSTemplateFormatVersion":"2010-09-09", "Description":"AWS CloudFormation Sample Template LAMP_Install_Only: ...", "Parameters":{ "KeyName":{ "..." }, "InstanceType":{ "..." }, "Mappings":{ "..." }, "Resources":{ "WebServerInstance":{ "Type":"AWS::EC2::Instance", "Metadata":{ "Comment1":"Configure the bootstrap helpers to install the Apache Web Server and PHP", "Comment2":"Save website content to /var/www/html/index.php", "AWS::CloudFormation::Init":{ "configSets":{ "Install":[ "Install" ] }, "Install":{ "packages":{ "yum":{ "mysql":[ ], "mysql-server":[ ], "mysql-libs":[ ], "httpd":[ ], "php":[ ], "php-mysql":[ ] } }, "files":{ "/var/www/html/index.php":{ "content":{ "Fn::Join":[ "", [ "<html>\n", " <head>\n", " <title>AWS CloudFormation PHP Sample</title>\n", " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\n", " </head>\n", " <body>\n", " <h1>Welcome to the AWS CloudFormation PHP Sample</h1>\n", " <p/>\n", " <?php\n", " // Print out the current data and time\n", " print \"The Current Date and Time is: <br/>\";\n", " print date(\"g:i A l, F j Y.\");\n", " ?>\n", " <p/>\n", " <?php\n", " // Setup a handle for CURL\n", " $curl_handle=curl_init();\n", " curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);\n", " curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);\n", " // Get the hostname of the instance from the instance metadata\n", " curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/latest/meta-data/public-hostname');\n", " $hostname = curl_exec($curl_handle);\n", " if (empty($hostname))\n", " {\n", " print \"Sorry, for some reason, we got no hostname back <br />\";\n", " }\n", " else\n", " {\n", " print \"Server = \" . $hostname . \"<br />\";\n", " }\n", " // Get the instance-id of the instance from the instance metadata\n", " curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/latest/meta-data/instance-id');\n", " $instanceid = curl_exec($curl_handle);\n", " if (empty($instanceid))\n", " {\n", " print \"Sorry, for some reason, we got no instance id back <br />\";\n", " }\n", " else\n", " {\n", " print \"EC2 instance-id = \" . $instanceid . \"<br />\";\n", " }\n", " $Database = \"", { "Ref":"DBName" }, "\";\n", " $DBUser = \"", { "Ref":"DBUsername" }, "\";\n", " $DBPassword = \"", { "Ref":"DBPassword" }, "\";\n", " print \"Database = \" . $Database . \"<br />\";\n", " $dbconnection = mysql_connect('localhost', $DBUser, $DBPassword, $Database)\n", " or die(\"Could not connect: \" . mysql_error());\n", " print (\"Connected to $Database successfully\");\n", " mysql_close($dbconnection);\n", " ?>\n", " <h2>PHP Information</h2>\n", " <p/>\n", " <?php\n", " phpinfo();\n", " ?>\n", " </body>\n", "</html>\n" ] ] }, "mode":"000600", "owner":"apache", "group":"apache" } }, "services":{ "sysvinit":{ "httpd":{ "enabled":"true", "ensureRunning":"true" } } } } }, "Properties":{ "ImageId":{ "Fn::FindInMap":[ "AWSRegionArch2AMI", { "Ref":"AWS::Region" }, { "Fn::FindInMap":[ "AWSInstanceType2Arch", { "Ref":"InstanceType" }, "Arch" ] } ] }, "InstanceType":{ "Ref":"InstanceType" }, "SecurityGroups":[ { "Ref":"WebServerSecurityGroup" } ], "KeyName":{ "Ref":"KeyName" }, "UserData":{ "Fn::Base64":{ "Fn::Join":[ "", [ "#!/bin/bash -xe\n", "yum install -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 WebServerInstance ", " --configsets Install ", " --region ", { "Ref":"AWS::Region" }, "\n" ] ] } } } }, "WebServerSecurityGroup":{ "..." } }, "Outputs":{ "..." } } } }

YAML

AWSTemplateFormatVersion: 2010-09-09 Description: 'AWS CloudFormation Sample Template LAMP_Install_Only: ...' Resources: WebServerInstance: Type: 'AWS::EC2::Instance' Metadata: Comment1: Configure the bootstrap helpers to install the Apache Web Server and PHP Comment2: Save website content to /var/www/html/index.php 'AWS::CloudFormation::Init': configSets: Install: - Install Install: packages: yum: mysql: [] mysql-server: [] mysql-libs: [] httpd: [] php: [] php-mysql: [] files: /var/www/html/index.php: content: !Join - '' - - | <html> - |2 <head> - |2 <title>AWS CloudFormation PHP Sample</title> - |2 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> - |2 </head> - |2 <body> - |2 <h1>Welcome to the AWS CloudFormation PHP Sample</h1> - |2 <p/> - |2 <?php - |2 // Print out the current data and time - |2 print "The Current Date and Time is: <br/>"; - |2 print date("g:i A l, F j Y."); - |2 ?> - |2 <p/> - |2 <?php - |2 // Setup a handle for CURL - |2 $curl_handle=curl_init(); - |2 curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2); - |2 curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1); - |2 // Get the hostname of the instance from the instance metadata - |2 curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/latest/meta-data/public-hostname'); - |2 $hostname = curl_exec($curl_handle); - |2 if (empty($hostname)) - |2 { - |2 print "Sorry, for some reason, we got no hostname back <br />"; - |2 } - |2 else - |2 { - |2 print "Server = " . $hostname . "<br />"; - |2 } - |2 // Get the instance-id of the instance from the instance metadata - |2 curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/latest/meta-data/instance-id'); - |2 $instanceid = curl_exec($curl_handle); - |2 if (empty($instanceid)) - |2 { - |2 print "Sorry, for some reason, we got no instance id back <br />"; - |2 } - |2 else - |2 { - |2 print "EC2 instance-id = " . $instanceid . "<br />"; - |2 } - ' $Database = "' - !Ref DBName - | "; - ' $DBUser = "' - !Ref DBUsername - | "; - ' $DBPassword = "' - !Ref DBPassword - | "; - |2 print "Database = " . $Database . "<br />"; - |2 $dbconnection = mysql_connect('localhost', $DBUser, $DBPassword, $Database) - |2 or die("Could not connect: " . mysql_error()); - |2 print ("Connected to $Database successfully"); - |2 mysql_close($dbconnection); - |2 ?> - |2 <h2>PHP Information</h2> - |2 <p/> - |2 <?php - |2 phpinfo(); - |2 ?> - |2 </body> - | </html> mode: '000600' owner: apache group: apache services: sysvinit: httpd: enabled: 'true' ensureRunning: 'true' Properties: ImageId: !FindInMap - AWSRegionArch2AMI - !Ref 'AWS::Region' - !FindInMap - AWSInstanceType2Arch - !Ref InstanceType - Arch InstanceType: !Ref InstanceType SecurityGroups: - !Ref WebServerSecurityGroup KeyName: !Ref KeyName UserData: !Base64 'Fn::Join': - '' - - | #!/bin/bash -xe - | yum install -y aws-cfn-bootstrap - | # Install the files and packages from the metadata - '/opt/aws/bin/cfn-init -v ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerInstance ' - ' --configsets Install ' - ' --region ' - !Ref 'AWS::Region' - |+

LAMP 組態

現在我們有一個安裝 Linux、ApacheSQL、My 和 的範本PHP,我們需要擴展範本,以便自動設定和執行 ApacheSQL、My 和 PHP。在下列範例中,我們擴展 Parameters 部分、AWS::CloudFormation::Init 資源和 UserData 屬性以完成設定。如同先前範本,為簡潔起見,將省略標示省略符號 (...) 的部分。範本中新增的部分會顯示為紅色斜體字。

範例定義的 DBUsernameDBPassword 參數已將其 NoEcho 屬性設為 true。如果您將NoEcho屬性設定為 true, 會針對描述堆疊或堆疊事件的任何呼叫 CloudFormation 傳回遮罩為星號 (*****) 的參數值,但存放在下列指定位置的資訊除外。

重要

使用 NoEcho 屬性不會遮罩任何儲存在下列資訊中的資訊:

我們強烈建議您不要使用這些機制來包含敏感資訊,例如密碼或秘密。

重要

我們建議您不要直接在 CloudFormation 範本中嵌入敏感資訊,而是在堆疊範本中使用動態參數,以參考存放在 外部和管理的敏感資訊 CloudFormation,例如在 AWS Systems Manager 參數存放區或 中 AWS Secrets Manager。

如需詳細資訊,請參閱請勿在您的範本中內嵌憑證最佳實務。

範例會新增更多參數,以取得設定 MySQL 資料庫的資訊,例如資料庫名稱、使用者名稱、密碼和根密碼。這些參數也包含限制條件,可在 CloudFormation 建立堆疊之前擷取格式不正確的值。

AWS::CloudFormation::Init 資源中,我們新增了我的SQL設定檔案,其中包含資料庫名稱、使用者名稱和密碼。此範例還新增 services 屬性,以確保 httpdmysqld 服務持續執行 (ensureRunning 設定為 true),並確保在執行個體重新啟動之後,這些服務也會重新啟動 (enabled 設定為 true)。比較好的做法是也同時包含 cfn-hup 協助程式指令碼,您可以用它對執行中的執行個體,透過更新堆疊範本來進行設定更新。例如,您可以變更範例PHP應用程式,然後執行堆疊更新來部署變更。

為了在安裝完成後執行 MySQL 命令,範例會新增另一個組態設定來執行命令。當您有一系列的任務必須以特定順序完成時,組態設定是有用的。此範例首先執行 Install 組態設定,然後執行 Configure 組態設定。Configure 組態設定指定資料庫根密碼,然後建立資料庫。在命令部分,依照名稱的字母順序處理命令,因此範例在每個命令名稱之前增加一個數字,以指示其執行順序。

JSON

{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "AWS CloudFormation Sample Template LAMP_Single_Instance: Create a LAMP stack using a single EC2 instance and a local MySQL database for storage. This template demonstrates using the AWS CloudFormation bootstrap scripts to install the packages and files necessary to deploy the Apache web server, PHP and MySQL at instance launch time. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template.", "Parameters" : { "KeyName" : { ... }, "DBName": { "Default": "MyDatabase", "Description" : "MySQL database name", "Type": "String", "MinLength": "1", "MaxLength": "64", "AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*", "ConstraintDescription" : "Must begin with a letter and contain only alphanumeric characters" }, "DBUsername": { "NoEcho": "true", "Description" : "Username for MySQL database access", "Type": "String", "MinLength": "1", "MaxLength": "16", "AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*", "ConstraintDescription" : "Must begin with a letter and contain only alphanumeric characters" }, "DBPassword": { "NoEcho": "true", "Description" : "Password for MySQL database access", "Type": "String", "MinLength": "1", "MaxLength": "41", "AllowedPattern" : "[a-zA-Z0-9]*", "ConstraintDescription" : "Must contain only alphanumeric characters" }, "DBRootPassword": { "NoEcho": "true", "Description" : "Root password for MySQL", "Type": "String", "MinLength": "1", "MaxLength": "41", "AllowedPattern" : "[a-zA-Z0-9]*", "ConstraintDescription" : "Must contain only alphanumeric characters" }, "InstanceType" : { ... } }, "Mappings" : { ... }, "Resources" : { "WebServerInstance": { "Type": "AWS::EC2::Instance", "Metadata" : { "Comment1" : "Configure the bootstrap helpers to install the Apache Web Server and PHP", "Comment2" : "Save website content to /var/www/html/index.php", "AWS::CloudFormation::Init" : { "configSets" : { "InstallAndRun" : [ "Install", "Configure" ] }, "Install" : { "packages" : { "yum" : { "mysql" : [], "mysql-server" : [], "mysql-libs" : [], "httpd" : [], "php" : [], "php-mysql" : [] } }, "files" : { "/var/www/html/index.php" : { "content" : { ... }, "mode" : "000600", "owner" : "apache", "group" : "apache" }, "/tmp/setup.mysql" : { "content" : { "Fn::Join" : ["", [ "CREATE DATABASE ", { "Ref" : "DBName" }, ";\n", "GRANT ALL ON ", { "Ref" : "DBName" }, ".* TO '", { "Ref" : "DBUsername" }, "'@localhost IDENTIFIED BY '", { "Ref" : "DBPassword" }, "';\n" ]]}, "mode" : "000400", "owner" : "root", "group" : "root" }, "/etc/cfn/cfn-hup.conf" : { "content" : { "Fn::Join" : ["", [ "[main]\n", "stack=", { "Ref" : "AWS::StackId" }, "\n", "region=", { "Ref" : "AWS::Region" }, "\n" ]]}, "mode" : "000400", "owner" : "root", "group" : "root" }, "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : { "content": { "Fn::Join" : ["", [ "[cfn-auto-reloader-hook]\n", "triggers=post.update\n", "path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n", "action=/opt/aws/bin/cfn-init -v ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerInstance ", " --configsets InstallAndRun ", " --region ", { "Ref" : "AWS::Region" }, "\n", "runas=root\n" ]]} } }, }, "services" : { "sysvinit" : { "mysqld" : { "enabled" : "true", "ensureRunning" : "true" }, "httpd" : { "enabled" : "true", "ensureRunning" : "true" }, "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]} } } }, "Configure" : { "commands" : { "01_set_mysql_root_password" : { "command" : { "Fn::Join" : ["", ["mysqladmin -u root password '", { "Ref" : "DBRootPassword" }, "'"]]}, "test" : { "Fn::Join" : ["", ["$(mysql ", { "Ref" : "DBUsername" }, " -u root --password='", { "Ref" : "DBRootPassword" }, "' >/dev/null 2>&1 </dev/null); (( $? != 0 ))"]]} }, "02_create_database" : { "command" : { "Fn::Join" : ["", ["mysql -u root --password='", { "Ref" : "DBRootPassword" }, "' < /tmp/setup.mysql"]]}, "test" : { "Fn::Join" : ["", ["$(mysql ", { "Ref" : "DBUsername" }, " -u root --password='", { "Ref" : "DBRootPassword" }, "' >/dev/null 2>&1 </dev/null); (( $? != 0 ))"]]} } } } } }, "Properties": { "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, "InstanceType" : { "Ref" : "InstanceType" }, "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ], "KeyName" : { "Ref" : "KeyName" }, "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash -xe\n", "yum install -y aws-cfn-bootstrap\n", "# Install the files and packages from the metadata\n", "/opt/aws/bin/cfn-init ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerInstance ", " --configsets InstallAndRun ", " --region ", { "Ref" : "AWS::Region" }, "\n" ]]}} } }, "WebServerSecurityGroup" : { ... } }, "Outputs" : { ... } }

YAML

AWSTemplateFormatVersion: 2010-09-09 Description: >- AWS CloudFormation Sample Template LAMP_Single_Instance: Create a LAMP stack using a single EC2 instance and a local MySQL database for storage. This template demonstrates using the AWS CloudFormation bootstrap scripts to install the packages and files necessary to deploy the Apache web server, PHP and MySQL at instance launch time. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template. Parameters: DBName: Default: MyDatabase Description: MySQL database name Type: String MinLength: '1' MaxLength: '64' AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*' ConstraintDescription: Must begin with a letter and contain only alphanumeric characters DBUsername: NoEcho: 'true' Description: Username for MySQL database access Type: String MinLength: '1' MaxLength: '16' AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*' ConstraintDescription: Must begin with a letter and contain only alphanumeric characters DBPassword: NoEcho: 'true' Description: Password for MySQL database access Type: String MinLength: '1' MaxLength: '41' AllowedPattern: '[a-zA-Z0-9]*' ConstraintDescription: Must contain only alphanumeric characters DBRootPassword: NoEcho: 'true' Description: Root password for MySQL Type: String MinLength: '1' MaxLength: '41' AllowedPattern: '[a-zA-Z0-9]*' ConstraintDescription: Must contain only alphanumeric characters Resources: WebServerInstance: Type: 'AWS::EC2::Instance' Metadata: Comment1: >- Configure the bootstrap helpers to install the Apache Web Server and PHP Comment2: Save website content to /var/www/html/index.php 'AWS::CloudFormation::Init': configSets: InstallAndRun: - Install - Configure Install: packages: yum: mysql: [] mysql-server: [] mysql-libs: [] httpd: [] php: [] php-mysql: [] files: /var/www/html/index.php: content: ...: null mode: '000600' owner: apache group: apache /tmp/setup.mysql: content: !Join - '' - - 'CREATE DATABASE ' - !Ref DBName - | ; - 'GRANT ALL ON ' - !Ref DBName - .* TO ' - !Ref DBUsername - '''@localhost IDENTIFIED BY ''' - !Ref DBPassword - | '; mode: '000400' owner: root group: root /etc/cfn/cfn-hup.conf: content: !Join - '' - - | [main] - stack= - !Ref 'AWS::StackId' - |+ - region= - !Ref 'AWS::Region' - |+ mode: '000400' owner: root group: root /etc/cfn/hooks.d/cfn-auto-reloader.conf: content: !Join - '' - - | [cfn-auto-reloader-hook] - | triggers=post.update - > path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init - 'action=/opt/aws/bin/cfn-init -v ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerInstance ' - ' --configsets InstallAndRun ' - ' --region ' - !Ref 'AWS::Region' - |+ - | runas=root services: sysvinit: mysqld: enabled: 'true' ensureRunning: 'true' httpd: enabled: 'true' ensureRunning: 'true' cfn-hup: enabled: 'true' ensureRunning: 'true' files: - /etc/cfn/cfn-hup.conf - /etc/cfn/hooks.d/cfn-auto-reloader.conf Configure: commands: 01_set_mysql_root_password: command: !Join - '' - - mysqladmin -u root password ' - !Ref DBRootPassword - '''' test: !Join - '' - - '$(mysql ' - !Ref DBUsername - ' -u root --password=''' - !Ref DBRootPassword - ''' >/dev/null 2>&1 </dev/null); (( $? != 0 ))' 02_create_database: command: !Join - '' - - mysql -u root --password=' - !Ref DBRootPassword - ''' < /tmp/setup.mysql' test: !Join - '' - - '$(mysql ' - !Ref DBUsername - ' -u root --password=''' - !Ref DBRootPassword - ''' >/dev/null 2>&1 </dev/null); (( $? != 0 ))' Properties: ImageId: !FindInMap - AWSRegionArch2AMI - !Ref 'AWS::Region' - !FindInMap - AWSInstanceType2Arch - !Ref InstanceType - Arch InstanceType: !Ref InstanceType SecurityGroups: - !Ref WebServerSecurityGroup KeyName: !Ref KeyName UserData: !Base64 'Fn::Join': - '' - - | #!/bin/bash -xe - | yum install -y aws-cfn-bootstrap - | # Install the files and packages from the metadata - '/opt/aws/bin/cfn-init ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerInstance ' - ' --configsets InstallAndRun ' - ' --region ' - !Ref 'AWS::Region' - |+ WebServerSecurityGroup: ...: Outputs: ...: ...

CreationPolicy 屬性

最後,您需要一種指示只有在所有服務 (例如 Apache 和 MySQL) 正在執行,而不是在所有堆疊資源建立之後 CloudFormation 才能完成堆疊建立。換句話說,如果您使用前面章節的範本來啟動堆疊, CloudFormation 會在成功建立所有資源之後,將堆疊的狀態設為 CREATE_COMPLETE。不過,如果一或多個 服務無法啟動, CloudFormation 仍會將堆疊狀態設定為 CREATE_COMPLETE。為了防止狀態在所有服務成功啟動之前變更為 CREATE_COMPLETE,您可以將 CreationPolicy 屬性 屬性新增至執行個體。此屬性會將執行個體的狀態置於 ,CREATE_IN_PROGRESS直到 CloudFormation 收到所需的成功訊號數或超過逾時期間為止,讓您可以控制執行個體何時成功建立。

下列範例會將建立政策新增至 Amazon EC2執行個體,以確保 cfn-init 在完成堆疊建立之前完成LAMP安裝和組態。結合建立政策,範例需要執行cfn-signal協助程式指令碼,以便在安裝和設定所有應用程式 CloudFormation 時發出訊號。

JSON

{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "AWS CloudFormation Sample Template LAMP_Single_Instance: ...", "Parameters" : { ... }, "Mappings" : { ... }, "Resources" : { "WebServerInstance": { "Type": "AWS::EC2::Instance", "Metadata" : { ... }, "Properties": { "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, "InstanceType" : { "Ref" : "InstanceType" }, "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ], "KeyName" : { "Ref" : "KeyName" }, "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash -xe\n", "yum update aws-cfn-bootstrap\n", "# Install the files and packages from the metadata\n", "/opt/aws/bin/cfn-init ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerInstance ", " --configsets InstallAndRun ", " --region ", { "Ref" : "AWS::Region" }, "\n", "# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerInstance ", " --region ", { "Ref" : "AWS::Region" }, "\n" ]]}} }, "CreationPolicy" : { "ResourceSignal" : { "Timeout" : "PT5M" } } }, "WebServerSecurityGroup" : { ... } }, "Outputs" : { "WebsiteURL" : { ... } } }

YAML

AWSTemplateFormatVersion: 2010-09-09 Description: 'AWS CloudFormation Sample Template LAMP_Single_Instance: ...' Resources: WebServerInstance: Type: 'AWS::EC2::Instance' Properties: ImageId: !FindInMap - AWSRegionArch2AMI - !Ref 'AWS::Region' - !FindInMap - AWSInstanceType2Arch - !Ref InstanceType - Arch InstanceType: !Ref InstanceType SecurityGroups: - !Ref WebServerSecurityGroup KeyName: !Ref KeyName UserData: !Base64 'Fn::Join': - '' - - | #!/bin/bash -xe - | yum update aws-cfn-bootstrap - | # Install the files and packages from the metadata - '/opt/aws/bin/cfn-init ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerInstance ' - ' --configsets InstallAndRun ' - ' --region ' - !Ref 'AWS::Region' - |+ - | # Signal the status from cfn-init - '/opt/aws/bin/cfn-signal -e $? ' - ' --stack ' - !Ref 'AWS::StackName' - "\_\_\_\_\_\_\_\_ --resource WebServerInstance " - ' --region ' - !Ref 'AWS::Region' - |+ CreationPolicy: ResourceSignal: Timeout: PT5M WebServerSecurityGroup: ...: ...

建立政策屬性使用 ISO 8601 格式來定義 5 分鐘的逾時期間。因為您只需等待 1 個執行個體進行設定,因此只需等待一個訊號,這是預設的計數。

UserData 屬性中,如果所有服務已成功完成設定並啟動,範本將執行 cfn-signal 指令碼來傳送成功訊號與結束代碼。當您使用 cfn-signal 指令碼時,必須包括堆疊 ID 或名稱,以及您要傳送訊號之目標資源的邏輯 ID。如果設定失敗,cfn-signal 將傳送失敗訊號,它會導致資源建立失敗。如果 CloudFormation 在逾時期限內沒有收到成功訊號,則建立資源也會失敗。

以下範例顯示最終完整範本。

您也可以在以下位置檢視範本:適用於 us-east-1 的 LAMP_Single_Instance.template AWS 區域。

JSON

{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "AWS CloudFormation Sample Template LAMP_Single_Instance: Create a LAMP stack using a single EC2 instance and a local MySQL database for storage. This template demonstrates using the AWS CloudFormation bootstrap scripts to install the packages and files necessary to deploy the Apache web server, PHP and MySQL at instance launch time. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template.", "Parameters" : { "KeyName": { "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instance", "Type": "AWS::EC2::KeyPair::KeyName", "ConstraintDescription" : "Can contain only ASCII characters." }, "DBName": { "Default": "MyDatabase", "Description" : "MySQL database name", "Type": "String", "MinLength": "1", "MaxLength": "64", "AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*", "ConstraintDescription" : "Must begin with a letter and contain only alphanumeric characters" }, "DBUsername": { "NoEcho": "true", "Description" : "User name for MySQL database access", "Type": "String", "MinLength": "1", "MaxLength": "16", "AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*", "ConstraintDescription" : "Must begin with a letter and contain only alphanumeric characters" }, "DBPassword": { "NoEcho": "true", "Description" : "Password for MySQL database access", "Type": "String", "MinLength": "1", "MaxLength": "41", "AllowedPattern" : "[a-zA-Z0-9]*", "ConstraintDescription" : "Must contain only alphanumeric characters" }, "DBRootPassword": { "NoEcho": "true", "Description" : "Root password for MySQL", "Type": "String", "MinLength": "1", "MaxLength": "41", "AllowedPattern" : "[a-zA-Z0-9]*", "ConstraintDescription" : "Must contain only alphanumeric characters" }, "InstanceType" : { "Description" : "WebServer EC2 instance type", "Type" : "String", "Default" : "t2.small", "AllowedValues" : [ "t1.micro", "t2.nano", "t2.micro", "t2.small", "t2.medium", "t2.large", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "g2.2xlarge", "g2.8xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "d2.xlarge", "d2.2xlarge", "d2.4xlarge", "d2.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge", "cg1.4xlarge" ], "ConstraintDescription" : "must be a valid EC2 instance type." }, "SSHLocation" : { "Description" : "The IP address range that can be used to SSH to the EC2 instances", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "0.0.0.0/0", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x" } }, "Mappings" : { "AWSInstanceType2Arch" : { "t1.micro" : { "Arch" : "HVM64" }, "t2.nano" : { "Arch" : "HVM64" }, "t2.micro" : { "Arch" : "HVM64" }, "t2.small" : { "Arch" : "HVM64" }, "t2.medium" : { "Arch" : "HVM64" }, "t2.large" : { "Arch" : "HVM64" }, "m1.small" : { "Arch" : "HVM64" }, "m1.medium" : { "Arch" : "HVM64" }, "m1.large" : { "Arch" : "HVM64" }, "m1.xlarge" : { "Arch" : "HVM64" }, "m2.xlarge" : { "Arch" : "HVM64" }, "m2.2xlarge" : { "Arch" : "HVM64" }, "m2.4xlarge" : { "Arch" : "HVM64" }, "m3.medium" : { "Arch" : "HVM64" }, "m3.large" : { "Arch" : "HVM64" }, "m3.xlarge" : { "Arch" : "HVM64" }, "m3.2xlarge" : { "Arch" : "HVM64" }, "m4.large" : { "Arch" : "HVM64" }, "m4.xlarge" : { "Arch" : "HVM64" }, "m4.2xlarge" : { "Arch" : "HVM64" }, "m4.4xlarge" : { "Arch" : "HVM64" }, "m4.10xlarge" : { "Arch" : "HVM64" }, "c1.medium" : { "Arch" : "HVM64" }, "c1.xlarge" : { "Arch" : "HVM64" }, "c3.large" : { "Arch" : "HVM64" }, "c3.xlarge" : { "Arch" : "HVM64" }, "c3.2xlarge" : { "Arch" : "HVM64" }, "c3.4xlarge" : { "Arch" : "HVM64" }, "c3.8xlarge" : { "Arch" : "HVM64" }, "c4.large" : { "Arch" : "HVM64" }, "c4.xlarge" : { "Arch" : "HVM64" }, "c4.2xlarge" : { "Arch" : "HVM64" }, "c4.4xlarge" : { "Arch" : "HVM64" }, "c4.8xlarge" : { "Arch" : "HVM64" }, "g2.2xlarge" : { "Arch" : "HVMG2" }, "g2.8xlarge" : { "Arch" : "HVMG2" }, "r3.large" : { "Arch" : "HVM64" }, "r3.xlarge" : { "Arch" : "HVM64" }, "r3.2xlarge" : { "Arch" : "HVM64" }, "r3.4xlarge" : { "Arch" : "HVM64" }, "r3.8xlarge" : { "Arch" : "HVM64" }, "i2.xlarge" : { "Arch" : "HVM64" }, "i2.2xlarge" : { "Arch" : "HVM64" }, "i2.4xlarge" : { "Arch" : "HVM64" }, "i2.8xlarge" : { "Arch" : "HVM64" }, "d2.xlarge" : { "Arch" : "HVM64" }, "d2.2xlarge" : { "Arch" : "HVM64" }, "d2.4xlarge" : { "Arch" : "HVM64" }, "d2.8xlarge" : { "Arch" : "HVM64" }, "hi1.4xlarge" : { "Arch" : "HVM64" }, "hs1.8xlarge" : { "Arch" : "HVM64" }, "cr1.8xlarge" : { "Arch" : "HVM64" }, "cc2.8xlarge" : { "Arch" : "HVM64" } }, "AWSRegionArch2AMI" : { "us-east-1" : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"}, "us-west-2" : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"}, "us-west-1" : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"}, "eu-west-1" : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"}, "eu-west-2" : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"}, "eu-west-3" : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"}, "eu-central-1" : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"}, "ap-northeast-1" : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"}, "ap-northeast-2" : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"}, "ap-northeast-3" : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"}, "ap-southeast-1" : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"}, "ap-southeast-2" : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"}, "ap-south-1" : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"}, "us-east-2" : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"}, "ca-central-1" : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"}, "sa-east-1" : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"}, "cn-north-1" : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"}, "cn-northwest-1" : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"} } }, "Resources" : { "WebServerInstance": { "Type": "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "configSets" : { "InstallAndRun" : [ "Install", "Configure" ] }, "Install" : { "packages" : { "yum" : { "mysql" : [], "mysql-server" : [], "mysql-libs" : [], "httpd" : [], "php" : [], "php-mysql" : [] } }, "files" : { "/var/www/html/index.php" : { "content" : { "Fn::Join" : [ "", [ "<html>\n", " <head>\n", " <title>AWS CloudFormation PHP Sample</title>\n", " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\n", " </head>\n", " <body>\n", " <h1>Welcome to the AWS CloudFormation PHP Sample</h1>\n", " <p/>\n", " <?php\n", " // Print out the current data and time\n", " print \"The Current Date and Time is: <br/>\";\n", " print date(\"g:i A l, F j Y.\");\n", " ?>\n", " <p/>\n", " <?php\n", " // Setup a handle for CURL\n", " $curl_handle=curl_init();\n", " curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);\n", " curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);\n", " // Get the hostname of the intance from the instance metadata\n", " curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/latest/meta-data/public-hostname');\n", " $hostname = curl_exec($curl_handle);\n", " if (empty($hostname))\n", " {\n", " print \"Sorry, for some reason, we got no hostname back <br />\";\n", " }\n", " else\n", " {\n", " print \"Server = \" . $hostname . \"<br />\";\n", " }\n", " // Get the instance-id of the intance from the instance metadata\n", " curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/latest/meta-data/instance-id');\n", " $instanceid = curl_exec($curl_handle);\n", " if (empty($instanceid))\n", " {\n", " print \"Sorry, for some reason, we got no instance id back <br />\";\n", " }\n", " else\n", " {\n", " print \"EC2 instance-id = \" . $instanceid . \"<br />\";\n", " }\n", " $Database = \"", {"Ref" : "DBName"}, "\";\n", " $DBUser = \"", {"Ref" : "DBUsername"}, "\";\n", " $DBPassword = \"", {"Ref" : "DBPassword"}, "\";\n", " print \"Database = \" . $Database . \"<br />\";\n", " $dbconnection = mysql_connect('localhost', $DBUser, $DBPassword, $Database)\n", " or die(\"Could not connect: \" . mysql_error());\n", " print (\"Connected to $Database successfully\");\n", " mysql_close($dbconnection);\n", " ?>\n", " <h2>PHP Information</h2>\n", " <p/>\n", " <?php\n", " phpinfo();\n", " ?>\n", " </body>\n", "</html>\n" ]]}, "mode" : "000600", "owner" : "apache", "group" : "apache" }, "/tmp/setup.mysql" : { "content" : { "Fn::Join" : ["", [ "CREATE DATABASE ", { "Ref" : "DBName" }, ";\n", "GRANT ALL ON ", { "Ref" : "DBName" }, ".* TO '", { "Ref" : "DBUsername" }, "'@localhost IDENTIFIED BY '", { "Ref" : "DBPassword" }, "';\n" ]]}, "mode" : "000400", "owner" : "root", "group" : "root" }, "/etc/cfn/cfn-hup.conf" : { "content" : { "Fn::Join" : ["", [ "[main]\n", "stack=", { "Ref" : "AWS::StackId" }, "\n", "region=", { "Ref" : "AWS::Region" }, "\n" ]]}, "mode" : "000400", "owner" : "root", "group" : "root" }, "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : { "content": { "Fn::Join" : ["", [ "[cfn-auto-reloader-hook]\n", "triggers=post.update\n", "path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n", "action=/opt/aws/bin/cfn-init -v ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerInstance ", " --configsets InstallAndRun ", " --region ", { "Ref" : "AWS::Region" }, "\n", "runas=root\n" ]]} } }, "services" : { "sysvinit" : { "mysqld" : { "enabled" : "true", "ensureRunning" : "true" }, "httpd" : { "enabled" : "true", "ensureRunning" : "true" }, "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]} } } }, "Configure" : { "commands" : { "01_set_mysql_root_password" : { "command" : { "Fn::Join" : ["", ["mysqladmin -u root password '", { "Ref" : "DBRootPassword" }, "'"]]}, "test" : { "Fn::Join" : ["", ["$(mysql ", { "Ref" : "DBUsername" }, " -u root --password='", { "Ref" : "DBRootPassword" }, "' >/dev/null 2>&1 </dev/null); (( $? != 0 ))"]]} }, "02_create_database" : { "command" : { "Fn::Join" : ["", ["mysql -u root --password='", { "Ref" : "DBRootPassword" }, "' < /tmp/setup.mysql"]]}, "test" : { "Fn::Join" : ["", ["$(mysql ", { "Ref" : "DBUsername" }, " -u root --password='", { "Ref" : "DBRootPassword" }, "' >/dev/null 2>&1 </dev/null); (( $? != 0 ))"]]} } } } } }, "Properties": { "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, "InstanceType" : { "Ref" : "InstanceType" }, "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ], "KeyName" : { "Ref" : "KeyName" }, "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash -xe\n", "yum install -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 WebServerInstance ", " --configsets InstallAndRun ", " --region ", { "Ref" : "AWS::Region" }, "\n", "# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerInstance ", " --region ", { "Ref" : "AWS::Region" }, "\n" ]]}} }, "CreationPolicy" : { "ResourceSignal" : { "Timeout" : "PT5M" } } }, "WebServerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable HTTP access via port 80", "SecurityGroupIngress" : [ {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"}, {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}} ] } } }, "Outputs" : { "WebsiteURL" : { "Description" : "URL for newly created LAMP stack", "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "WebServerInstance", "PublicDnsName" ]}]] } } } }

YAML

AWSTemplateFormatVersion: 2010-09-09 Description: >- AWS CloudFormation Sample Template LAMP_Single_Instance: Create a LAMP stack using a single EC2 instance and a local MySQL database for storage. This template demonstrates using the AWS CloudFormation bootstrap scripts to install the packages and files necessary to deploy the Apache web server, PHP and MySQL at instance launch time. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template. Parameters: KeyName: Description: Name of an existing EC2 KeyPair to enable SSH access to the instance Type: 'AWS::EC2::KeyPair::KeyName' ConstraintDescription: must be the name of an existing EC2 KeyPair. DBName: Default: MyDatabase Description: MySQL database name Type: String MinLength: '1' MaxLength: '64' AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*' ConstraintDescription: must begin with a letter and contain only alphanumeric characters. DBUser: NoEcho: 'true' Description: Username for MySQL database access Type: String MinLength: '1' MaxLength: '16' AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*' ConstraintDescription: must begin with a letter and contain only alphanumeric characters. DBPassword: NoEcho: 'true' Description: Password for MySQL database access Type: String MinLength: '1' MaxLength: '41' AllowedPattern: '[a-zA-Z0-9]*' ConstraintDescription: must contain only alphanumeric characters. DBRootPassword: NoEcho: 'true' Description: Root password for MySQL Type: String MinLength: '1' MaxLength: '41' AllowedPattern: '[a-zA-Z0-9]*' ConstraintDescription: must contain only alphanumeric characters. InstanceType: Description: WebServer EC2 instance type Type: String Default: t2.small AllowedValues: - t1.micro - t2.nano - t2.micro - t2.small - t2.medium - t2.large - m1.small - m1.medium - m1.large - m1.xlarge - m2.xlarge - m2.2xlarge - m2.4xlarge - m3.medium - m3.large - m3.xlarge - m3.2xlarge - m4.large - m4.xlarge - m4.2xlarge - m4.4xlarge - m4.10xlarge - c1.medium - c1.xlarge - c3.large - c3.xlarge - c3.2xlarge - c3.4xlarge - c3.8xlarge - c4.large - c4.xlarge - c4.2xlarge - c4.4xlarge - c4.8xlarge - g2.2xlarge - g2.8xlarge - r3.large - r3.xlarge - r3.2xlarge - r3.4xlarge - r3.8xlarge - i2.xlarge - i2.2xlarge - i2.4xlarge - i2.8xlarge - d2.xlarge - d2.2xlarge - d2.4xlarge - d2.8xlarge - hi1.4xlarge - hs1.8xlarge - cr1.8xlarge - cc2.8xlarge - cg1.4xlarge ConstraintDescription: must be a valid EC2 instance type. SSHLocation: Description: ' The IP address range that can be used to SSH to the EC2 instances' Type: String MinLength: '9' MaxLength: '18' Default: 0.0.0.0/0 AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Mappings: AWSInstanceType2Arch: t1.micro: Arch: HVM64 t2.nano: Arch: HVM64 t2.micro: Arch: HVM64 t2.small: Arch: HVM64 t2.medium: Arch: HVM64 t2.large: Arch: HVM64 m1.small: Arch: HVM64 m1.medium: Arch: HVM64 m1.large: Arch: HVM64 m1.xlarge: Arch: HVM64 m2.xlarge: Arch: HVM64 m2.2xlarge: Arch: HVM64 m2.4xlarge: Arch: HVM64 m3.medium: Arch: HVM64 m3.large: Arch: HVM64 m3.xlarge: Arch: HVM64 m3.2xlarge: Arch: HVM64 m4.large: Arch: HVM64 m4.xlarge: Arch: HVM64 m4.2xlarge: Arch: HVM64 m4.4xlarge: Arch: HVM64 m4.10xlarge: Arch: HVM64 c1.medium: Arch: HVM64 c1.xlarge: Arch: HVM64 c3.large: Arch: HVM64 c3.xlarge: Arch: HVM64 c3.2xlarge: Arch: HVM64 c3.4xlarge: Arch: HVM64 c3.8xlarge: Arch: HVM64 c4.large: Arch: HVM64 c4.xlarge: Arch: HVM64 c4.2xlarge: Arch: HVM64 c4.4xlarge: Arch: HVM64 c4.8xlarge: Arch: HVM64 g2.2xlarge: Arch: HVMG2 g2.8xlarge: Arch: HVMG2 r3.large: Arch: HVM64 r3.xlarge: Arch: HVM64 r3.2xlarge: Arch: HVM64 r3.4xlarge: Arch: HVM64 r3.8xlarge: Arch: HVM64 i2.xlarge: Arch: HVM64 i2.2xlarge: Arch: HVM64 i2.4xlarge: Arch: HVM64 i2.8xlarge: Arch: HVM64 d2.xlarge: Arch: HVM64 d2.2xlarge: Arch: HVM64 d2.4xlarge: Arch: HVM64 d2.8xlarge: Arch: HVM64 hi1.4xlarge: Arch: HVM64 hs1.8xlarge: Arch: HVM64 cr1.8xlarge: Arch: HVM64 cc2.8xlarge: Arch: HVM64 AWSInstanceType2NATArch: t1.micro: Arch: NATHVM64 t2.nano: Arch: NATHVM64 t2.micro: Arch: NATHVM64 t2.small: Arch: NATHVM64 t2.medium: Arch: NATHVM64 t2.large: Arch: NATHVM64 m1.small: Arch: NATHVM64 m1.medium: Arch: NATHVM64 m1.large: Arch: NATHVM64 m1.xlarge: Arch: NATHVM64 m2.xlarge: Arch: NATHVM64 m2.2xlarge: Arch: NATHVM64 m2.4xlarge: Arch: NATHVM64 m3.medium: Arch: NATHVM64 m3.large: Arch: NATHVM64 m3.xlarge: Arch: NATHVM64 m3.2xlarge: Arch: NATHVM64 m4.large: Arch: NATHVM64 m4.xlarge: Arch: NATHVM64 m4.2xlarge: Arch: NATHVM64 m4.4xlarge: Arch: NATHVM64 m4.10xlarge: Arch: NATHVM64 c1.medium: Arch: NATHVM64 c1.xlarge: Arch: NATHVM64 c3.large: Arch: NATHVM64 c3.xlarge: Arch: NATHVM64 c3.2xlarge: Arch: NATHVM64 c3.4xlarge: Arch: NATHVM64 c3.8xlarge: Arch: NATHVM64 c4.large: Arch: NATHVM64 c4.xlarge: Arch: NATHVM64 c4.2xlarge: Arch: NATHVM64 c4.4xlarge: Arch: NATHVM64 c4.8xlarge: Arch: NATHVM64 g2.2xlarge: Arch: NATHVMG2 g2.8xlarge: Arch: NATHVMG2 r3.large: Arch: NATHVM64 r3.xlarge: Arch: NATHVM64 r3.2xlarge: Arch: NATHVM64 r3.4xlarge: Arch: NATHVM64 r3.8xlarge: Arch: NATHVM64 i2.xlarge: Arch: NATHVM64 i2.2xlarge: Arch: NATHVM64 i2.4xlarge: Arch: NATHVM64 i2.8xlarge: Arch: NATHVM64 d2.xlarge: Arch: NATHVM64 d2.2xlarge: Arch: NATHVM64 d2.4xlarge: Arch: NATHVM64 d2.8xlarge: Arch: NATHVM64 hi1.4xlarge: Arch: NATHVM64 hs1.8xlarge: Arch: NATHVM64 cr1.8xlarge: Arch: NATHVM64 cc2.8xlarge: Arch: NATHVM64 AWSRegionArch2AMI: af-south-1: HVM64: ami-064cc455f8a1ef504 HVMG2: NOT_SUPPORTED ap-east-1: HVM64: ami-f85b1989 HVMG2: NOT_SUPPORTED ap-northeast-1: HVM64: ami-0b2c2a754d5b4da22 HVMG2: ami-09d0e0e099ecabba2 ap-northeast-2: HVM64: ami-0493ab99920f410fc HVMG2: NOT_SUPPORTED ap-northeast-3: HVM64: ami-01344f6f63a4decc1 HVMG2: NOT_SUPPORTED ap-south-1: HVM64: ami-03cfb5e1fb4fac428 HVMG2: ami-0244c1d42815af84a ap-southeast-1: HVM64: ami-0ba35dc9caf73d1c7 HVMG2: ami-0e46ce0d6a87dc979 ap-southeast-2: HVM64: ami-0ae99b503e8694028 HVMG2: ami-0c0ab057a101d8ff2 ca-central-1: HVM64: ami-0803e21a2ec22f953 HVMG2: NOT_SUPPORTED cn-north-1: HVM64: ami-07a3f215cc90c889c HVMG2: NOT_SUPPORTED cn-northwest-1: HVM64: ami-0a3b3b10f714a0ff4 HVMG2: NOT_SUPPORTED eu-central-1: HVM64: ami-0474863011a7d1541 HVMG2: ami-0aa1822e3eb913a11 eu-north-1: HVM64: ami-0de4b8910494dba0f HVMG2: ami-32d55b4c eu-south-1: HVM64: ami-08427144fe9ebdef6 HVMG2: NOT_SUPPORTED eu-west-1: HVM64: ami-015232c01a82b847b HVMG2: ami-0d5299b1c6112c3c7 eu-west-2: HVM64: ami-0765d48d7e15beb93 HVMG2: NOT_SUPPORTED eu-west-3: HVM64: ami-0caf07637eda19d9c HVMG2: NOT_SUPPORTED me-south-1: HVM64: ami-0744743d80915b497 HVMG2: NOT_SUPPORTED sa-east-1: HVM64: ami-0a52e8a6018e92bb0 HVMG2: NOT_SUPPORTED us-east-1: HVM64: ami-032930428bf1abbff HVMG2: ami-0aeb704d503081ea6 us-east-2: HVM64: ami-027cab9a7bf0155df HVMG2: NOT_SUPPORTED us-west-1: HVM64: ami-088c153f74339f34c HVMG2: ami-0a7fc72dc0e51aa77 us-west-2: HVM64: ami-01fee56b22f308154 HVMG2: ami-0fe84a5b4563d8f27 Resources: WebServerInstance: Type: 'AWS::EC2::Instance' Metadata: 'AWS::CloudFormation::Init': configSets: InstallAndRun: - Install - Configure Install: packages: yum: mysql: [] mysql-server: [] mysql-libs: [] httpd: [] php: [] php-mysql: [] files: /var/www/html/index.php: content: !Join - '' - - | <html> - |2 <head> - |2 <title>AWS CloudFormation PHP Sample</title> - |2 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> - |2 </head> - |2 <body> - |2 <h1>Welcome to the AWS CloudFormation PHP Sample</h1> - |2 <p/> - |2 <?php - |2 // Print out the current data and time - |2 print "The Current Date and Time is: <br/>"; - |2 print date("g:i A l, F j Y."); - |2 ?> - |2 <p/> - |2 <?php - |2 // Setup a handle for CURL - |2 $curl_handle=curl_init(); - |2 curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2); - |2 curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1); - |2 // Get the hostname of the intance from the instance metadata - |2 curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/latest/meta-data/public-hostname'); - |2 $hostname = curl_exec($curl_handle); - |2 if (empty($hostname)) - |2 { - |2 print "Sorry, for some reason, we got no hostname back <br />"; - |2 } - |2 else - |2 { - |2 print "Server = " . $hostname . "<br />"; - |2 } - |2 // Get the instance-id of the intance from the instance metadata - |2 curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/latest/meta-data/instance-id'); - |2 $instanceid = curl_exec($curl_handle); - |2 if (empty($instanceid)) - |2 { - |2 print "Sorry, for some reason, we got no instance id back <br />"; - |2 } - |2 else - |2 { - |2 print "EC2 instance-id = " . $instanceid . "<br />"; - |2 } - |2 $Database = "localhost"; - ' $DBUser = "' - !Ref DBUser - | "; - ' $DBPassword = "' - !Ref DBPassword - | "; - |2 print "Database = " . $Database . "<br />"; - |2 $dbconnection = mysql_connect($Database, $DBUser, $DBPassword) - |2 or die("Could not connect: " . mysql_error()); - |2 print ("Connected to $Database successfully"); - |2 mysql_close($dbconnection); - |2 ?> - |2 <h2>PHP Information</h2> - |2 <p/> - |2 <?php - |2 phpinfo(); - |2 ?> - |2 </body> - | </html> mode: '000600' owner: apache group: apache /tmp/setup.mysql: content: !Join - '' - - 'CREATE DATABASE ' - !Ref DBName - | ; - 'GRANT ALL ON ' - !Ref DBName - .* TO ' - !Ref DBUser - '''@localhost IDENTIFIED BY ''' - !Ref DBPassword - | '; mode: '000400' owner: root group: root /etc/cfn/cfn-hup.conf: content: !Join - '' - - | [main] - stack= - !Ref 'AWS::StackId' - |+ - region= - !Ref 'AWS::Region' - |+ mode: '000400' owner: root group: root /etc/cfn/hooks.d/cfn-auto-reloader.conf: content: !Join - '' - - | [cfn-auto-reloader-hook] - | triggers=post.update - > path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init - 'action=/opt/aws/bin/cfn-init -v ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerInstance ' - ' --configsets InstallAndRun ' - ' --region ' - !Ref 'AWS::Region' - |+ - | runas=root mode: '000400' owner: root group: root services: sysvinit: mysqld: enabled: 'true' ensureRunning: 'true' httpd: enabled: 'true' ensureRunning: 'true' cfn-hup: enabled: 'true' ensureRunning: 'true' files: - /etc/cfn/cfn-hup.conf - /etc/cfn/hooks.d/cfn-auto-reloader.conf Configure: commands: 01_set_mysql_root_password: command: !Join - '' - - mysqladmin -u root password ' - !Ref DBRootPassword - '''' test: !Join - '' - - '$(mysql ' - !Ref DBName - ' -u root --password=''' - !Ref DBRootPassword - ''' >/dev/null 2>&1 </dev/null); (( $? != 0 ))' 02_create_database: command: !Join - '' - - mysql -u root --password=' - !Ref DBRootPassword - ''' < /tmp/setup.mysql' test: !Join - '' - - '$(mysql ' - !Ref DBName - ' -u root --password=''' - !Ref DBRootPassword - ''' >/dev/null 2>&1 </dev/null); (( $? != 0 ))' Properties: ImageId: !FindInMap - AWSRegionArch2AMI - !Ref 'AWS::Region' - !FindInMap - AWSInstanceType2Arch - !Ref InstanceType - Arch InstanceType: !Ref InstanceType SecurityGroups: - !Ref WebServerSecurityGroup KeyName: !Ref KeyName UserData: !Base64 'Fn::Join': - '' - - | #!/bin/bash -xe - | yum update -y aws-cfn-bootstrap - | # Install the files and packages from the metadata - '/opt/aws/bin/cfn-init -v ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerInstance ' - ' --configsets InstallAndRun ' - ' --region ' - !Ref 'AWS::Region' - |+ - | # Signal the status from cfn-init - '/opt/aws/bin/cfn-signal -e $? ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerInstance ' - ' --region ' - !Ref 'AWS::Region' - |+ CreationPolicy: ResourceSignal: Timeout: PT5M WebServerSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Enable HTTP access via port 80 SecurityGroupIngress: - IpProtocol: tcp FromPort: '80' ToPort: '80' CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: '22' ToPort: '22' CidrIp: !Ref SSHLocation Outputs: WebsiteURL: Description: URL for newly created LAMP stack Value: !Join - '' - - 'http://' - !GetAtt - WebServerInstance - PublicDnsName