1. 程式人生 > >AWS學習筆記(六)--利用CloudFormation管理AWS資源

AWS學習筆記(六)--利用CloudFormation管理AWS資源

view sdm ces top 結構 iat param nfs-utils creat

CloudFormation是管理AWS資源的一項服務。你可以創建一個Template,其中包括所有用到的資源(VPC、EC2、RDS等)。Template支持參數化,可根據條件創建資源,以適應不同的環境。CloudFormation另一個重要概念是Stack,每個Stack包含一個Template,可以設定Template中定義的參數值,增加Stack級tag,設置權限等,通過Stack真正的創建資源。

利用CloudFormation不必再單獨的創建和配置AWS資源,解除了繁瑣的手工安裝配置工作,又可以將代碼進行版本管理,利於以後的更新維護,也不用編寫安裝手冊了。

Template

CloudFormation Template支持兩種格式:JSON和YAML,可以將模板文件保存為任何擴展名,比如:.json, .yaml, .template, .txt。YAML語法更簡捷易讀,並且支持註釋,但CloudFormation Designer目前只支持JSON。

JSON示例

{  
  "AWSTemplateFormatVersion" : "2010-09-09",  
  "Description" : "A sample template",  
  "Resources" : {  
    "MyEC2Instance" : {  
      "Type" : "AWS::EC2::Instance",  
      "Properties" : {  
        "ImageId" : "ami-2f726546",  
        "InstanceType" : "t1.micro",  
        "KeyName" : "testkey",  
        "BlockDeviceMappings" : [  
          {  
            "DeviceName" : "/dev/sdm",  
            "Ebs" : {  
              "VolumeType" : "io1",  
              "Iops" : "200",  
              "DeleteOnTermination" : "false",  
              "VolumeSize" : "20"  
            }  
          }  
        ]  
      }  
    }  
  }  
}

YAML示例

AWSTemplateFormatVersion: "2010-09-09"  
Description: A sample template  
Resources:  
  MyEC2Instance:  
    Type: "AWS::EC2::Instance"  
    Properties:   
      ImageId: "ami-2f726546"  
      InstanceType: t1.micro  
      KeyName: testkey  
      BlockDeviceMappings:  
        -  
          DeviceName: /dev/sdm  
          Ebs:  
            VolumeType: io1  
            Iops: 200  
            DeleteOnTermination: false  
            VolumeSize: 20

模板基本知識請參考:
Template Anatomy
Learn Template Basics
Parameters
參數類型除String、Number、List<Number>、CommaDelimitedList外,還支持特定的類型,比如AWS::EC2::KeyPair::KeyName、AWS::EC2::AvailabilityZone::Name、AWS::EC2::SecurityGroup::GroupName等,用戶必須指定其賬戶中現有的 AWS 值。

在通過CloudFormation Console創建Stack時,參數默認是按字母排序的,如果參數多看起來會很亂,不易查找,這就需要借助Metadata了,AWS::CloudFormation::Interface用於定義參數在CloudFormation控制臺中的分組和排序方式:

"Metadata" : {  
  "AWS::CloudFormation::Interface" : {  
    "ParameterGroups" : [  
      {  
        "Label" : { "default" : "Network Configuration" },  
        "Parameters" : [ "VPCID", "SubnetId", "SecurityGroupID" ]  
      },  
      {  
        "Label" : { "default":"Amazon EC2 Configuration" },  
        "Parameters" : [ "InstanceType", "KeyName" ]  
      }  
    ]  
  }  
}

下面的代碼演示了CloudFormation中cfn-init和shell的使用。AMI使用了RHEL 7,其中包括安裝cfn-init、awscli、awslogs,配置DNS、awscli、awslog等。

"AWSTemplateFormatVersion": "2010-09-09",  
  "Resources": {  
    "InstanceTest": {  
      "Type": "AWS::EC2::Instance",  
      "Metadata": {  
        "AWS::CloudFormation::Init": {  
          "configSets": {  
            "Install": [  
              "Install"  
            ]  
          },  
          "Install": {  
            "packages": {  
              "yum": {  
                "ntp": [],  
                "nfs-utils": [],  
                "rpcbind": []  
              }  
            },  
            "files": {  
              "/etc/sysconfig/network-scripts/ifcfg-eth0": {  
                "content": { "Fn::Join": ["", [  
                  "DEVICE=\"eth0\"\n",  
                  "BOOTPROTO=\"dhcp\"\n",  
                  "ONBOOT=\"yes\"\n",  
                  "TYPE=\"Ethernet\"\n",  
                  "USERCTL=\"yes\"\n",  
                  "PEERDNS=\"no\"\n",  
                  "IPV6INIT=\"no\"\n",  
                  "DNS1=\"10.184.13.14\""  
                ]]},  
                "owner": "root",  
                "group": "root"  
              },  
              "/root/.aws/config": {  
                "content": { "Fn::Join": ["", [
                                  "[default]\n",  
                  "output = json\n",  
                  "region = cn-north-1"  
                ]]},  
                "mode": "000600",  
                "owner": "root",  
                "group": "root"  
              },  
              "/root/.aws/credentials": {  
                "content": { "Fn::Join": ["", [  
                  "[default]\n",  
                  "aws_access_key_id = AKIAPM6UDU6DGZPYXXXX\n",   
                  "aws_secret_access_key = CrYrR/LeiDXJWbAX3KQwFnaScDU0zGE+XXXXXXXX"  
                ]]},  
                "mode": "000600",  
                "owner": "root",  
                "group": "root"  
              },  
              "/root/.aws/awslogs.conf": {  
                "content": { "Fn::Join": ["", [  
                  "[general]\n",  
                  "state_file = /var/awslogs/state/agent-state\n",  
                  "[/var/log/messages]\n",  
                  "datetime_format = %Y-%m-%d %H:%M:%S\n",  
                  "file = /var/log/messages\n",  
                  "buffer_duration = 5000\n",  
                  "log_stream_name = server-log\n",  
                  "initial_position = start_of_file\n",  
                  "log_group_name = /var/log/messages"  
                ]]},  
                "mode": "000600",  
                "owner": "root",  
                "group": "root"  
              }  
            },
                        "commands": {  
              "1-timezone": {  
                "command": "timedatectl set-timezone UTC",  
                "ignoreErrors": "true"  
              },  
              "2-groups": {  
                "command": "groupadd -g 1001 monet",  
                "ignoreErrors": "true"  
              },  
              "3-users": {  
                "command": "useradd -d /monet -g monet -u 1001 monetmanager\nchmod 755 /monet ",  
                "ignoreErrors": "true"  
              }  
            },  
            "services": {  
              "sysvinit": {  
                "ntpd": { "enabled" : "true", "ensureRunning" : "true" },  
                "rpcbind": { "enabled" : "true", "ensureRunning" : "true" },  
                "nfslock": { "enabled" : "true", "ensureRunning" : "true" }  
              }  
            }  
          }  
        }  
      },  
      "Properties": {  
        "AvailabilityZone": "cn-north-1a",  
        "DisableApiTermination": "false",  
        "EbsOptimized": "false",  
        "ImageId": "ami-3ce23651",  
        "InstanceInitiatedShutdownBehavior": "stop",  
        "InstanceType": "t2.small",  
        "KeyName": "Prod Key Pair",  
        "Monitoring": "false",  
        "PrivateIpAddress": "10.184.12.247",
                "SecurityGroupIds": [  
          {  
            "Fn::ImportValue": "prod-network-sg-private-id"  
          }  
        ],  
        "SubnetId": {  
          "Fn::ImportValue": "prod-network-subnet-private-id"  
        },  
        "BlockDeviceMappings": [  
          {  
            "DeviceName": "/dev/sda1",  
            "Ebs": {  
              "VolumeSize": "30"  
            }  
          }  
        ],  
        "Tags": [  
          {  
            "Key": "Name",  
            "Value": "test-ec2"  
          }  
        ],  
        "UserData": {  
          "Fn::Base64": {  
            "Fn::Join" : ["", [  
                "#!/bin/bash\n",  

                "# Install cfn-init\n",  
                "curl -O https://bootstrap.pypa.io/ez_setup.py\n",  
                "python ez_setup.py\n",  
                "easy_install --script-dir /opt/aws/bin https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",  

                "# Install the files and packages from the metadata\n",  
                "/opt/aws/bin/cfn-init -v ",  
                "         --stack ", { "Ref" : "AWS::StackName" },  
                "         --resource InstanceTest ",  
                "         --configsets Install ",  
                "         --region ", { "Ref" : "AWS::Region" }, "\n",  

                "# Install awscli\n",  
                "curl -O https://bootstrap.pypa.io/get-pip.py\n",  
                "python get-pip.py\n",  
                "pip install awscli\n", 

                                "# Install awslogs\n",  
                "curl -O https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py\n",  
                "python ./awslogs-agent-setup.py --region cn-north-1 --non-interactive --configfile=/root/.aws/awslogs.conf\n",  

                "# Delete installation files\n",  
                "rm -f get-pip.py ez_setup.py setuptools*.zip awslogs-agent-setup.py\n"  
              ]  
            ]  
          }  
        }  
      }  
    }  
  }  
}

下面演示了在Windows 2016上通過powershell安裝DNS:

{  
  "AWSTemplateFormatVersion": "2010-09-09",  
  "Resources": {  
    "InstanceDNS": {  
      "Type": "AWS::EC2::Instance",  
      "Properties": {  
        "AvailabilityZone": "cn-north-1a",  
        "DisableApiTermination": "false",  
        "EbsOptimized": "false",  
        "ImageId": "ami-2797404a",  
        "InstanceInitiatedShutdownBehavior": "stop",  
        "InstanceType": "t2.small",  
        "KeyName": "Prod Key Pair",  
        "Monitoring": "false",  
        "PrivateIpAddress": "10.184.13.15",  
        "SecurityGroupIds": [  
          "sg-b0525cd5"  
        ],  
        "SubnetId": "subnet-a65208c3",  
        "BlockDeviceMappings": [  
          {  
            "DeviceName": "/dev/sda1",  
            "Ebs": {  
              "VolumeSize": "30"  
            }  
          }  
        ],  
        "UserData": { "Fn::Base64" : { "Fn::Join" : ["", [  
          "<powershell>\n",  
          "Install-WindowsFeature -Name DNS -IncludeManagementTools\n",  
          "Add-DnsServerPrimaryZone -Name \"iata.org\" -ZoneFile \"iata.org.dns\"\n",  
          "Add-DnsServerResourceRecordA -Name \"test\" -ZoneName \"iata.org\" -AllowUpdateAny -IPv4Address \"10.184.12.111\"\n",  
          "</powershell>"  
        ]]}},  
        "Tags": [  
          {  
            "Key": "Name",  
            "Value": "test-dns"  
          }  
        ]  
      }  
    }  
  }  
}

CloudFormation Designer

AWS CloudFormation Console提供圖形化的Template設計器,支持拖拽操作,集成JSON編輯器,支持自動完成功能。
使用CloudFormation Designer的拖拽功能,或用其打開已有的Template會增加組件位置信息,這些信息在實際應用中是沒有必要的,也增加了Template的復雜度,故本人只利用它的自動完成功能,要編輯已有的Template時,使用Copy/Paste的方式。

快捷鍵
【Ctrl+Shift+Space】 顯示提示列表
【Ctrl+F】 搜索
【Ctrl+\】 格式化Template(會刪除所有空行)
【Ctrl+Shift+\】 刪除所有空格

Sample Templates

CloudFormation提供了大量的示例模板Sample Templates可供學習,其中China Region的示例較少,推薦US West (Northern California) Region。比如Services中下面的示例,全面演示了從創建VPC到EC2。
Creates a VPC and adds an Amazon EC2 instance with an Elastic IP address and a security group

CloudFormer

CloudFormer是模板創建工具,可從現有AWS資源創建CloudFormation Template,用來作為初始Template,是學習Template語法結構的好工具。

CloudFormer使用很簡單,它是一個CloudFormation Stack,可從CloudFormation Console創建,創建後在一個EC2實例上運行,不需其他資源。

創建CloudFormer
登錄CloudFormation Console > Create New Stack > Select a sample template > CloudFormer > Next > 輸入Stack name、Username、Password > 根據提示信息完成後續步驟

啟動CloudFormer
點擊CloudFormer Stack選項卡Outputs中的鏈接,輸入用戶名,密碼即可啟動CloudFormer。然後Select the AWS Region > Create Template > 一步步的選擇要創建模板的資源。

註:如出現錯誤NoMethodError in TemplatesController,可能是資源配置有問題,試著減少一些資源。

Best Practices

  • 按生命周期和所有權組織堆棧,而不是將所有資源放在一個Stack內,避免資源變化時互相影響。另外,可以根據層次結構和面向的服務(SOA)劃分資源。
  • 使用跨堆棧引用來導出共享資源,其他堆棧使用 Fn::ImportValue函數調用導出的資源。引用另一個 AWS CloudFormation 堆棧中的資源輸出
  • 重復使用模板以在多個環境中復制堆棧,要使模板可重用,可使用參數、映射和條件部分,以便能在創建堆棧時對其進行自定義。
  • 使用嵌套堆棧來重復使用常見模板,要創建嵌套堆棧,可使用模板中的AWS::CloudFormation::Stack資源來引用其他模板。

AWS CloudFormation CLI

Creating a Stack

You must provide the stack name, the location of a valid template, and any input parameters. If you specify a local template file, AWS CloudFormation uploads it to an Amazon S3 bucket in your AWS account.

$ aws cloudformation create-stack --stack-name myteststack --template-body file:///home/testuser/mytemplate.json --parameters ParameterKey=Parm1,ParameterValue=test1 ParameterKey=Parm2,ParameterValue=test2

Listing Your Stacks

Note The aws cloudformation list-stacks command returns information on deleted stacks for 90 days after they have been deleted.

$ aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE

Describing Your Stacks

$ aws cloudformation describe-stacks --stack-name myteststack

By default, aws cloudformation describe-stacks returns parameter values. To prevent sensitive parameter values such as passwords from being returned, include a NoEcho property set to TRUE in your AWS CloudFormation template.

Viewing Stack Event History

You can track the status of the resources AWS CloudFormation is creating and deleting with the aws cloudformation describe-stack-events command. The amount of time to create or delete a stack depends on the complexity of your stack.

$ aws cloudformation describe-stack-events --stack-name myteststack

Listing Stack Resources

$ aws cloudformation list-stack-resources --stack-name myteststack

Retrieving a Template

AWS CloudFormation stores the template you use to create your stack as part of the stack.

$ aws cloudformation get-template --stack-name myteststack

Validating a Template

You can validate templates locally by using the --template-body parameter, or remotely with the --template-url parameter.

$ aws cloudformation validate-template --template-url https://s3.amazonaws.com/cloudformation-templates-us-east-1/S3_Bucket.template
$ aws cloudformation validate-template --template-body file:///home/local/test/sampletemplate.json

Deleting a Stack

$ aws cloudformation delete-stack --stack-name myteststack

Getting Started with AWS CloudFormation
Template Anatomy
Learn Template Basics
AWS CloudFormation Templates
AWS Resource Types Reference
Using CloudFormer to Create AWS CloudFormation Templates from Existing AWS Resources
Using the AWS Command Line Interface
AWS CloudFormation Best Practices
Install roles, role services, and features by using Windows PowerShell cmdlets
Domain Name System (DNS) Server Cmdlets

AWS學習筆記(六)--利用CloudFormation管理AWS資源