草庐IT

AWS CloudFormation 系列--(1)快速入门

liuqianglong.com 2023-05-27 原文

AWS CloudFormation 系列–(1)快速入门

B站视频链接:https://www.bilibili.com/video/BV1Wd4y1i7PE/?spm_id_from=333.999.0.0
微信公众号自刘地

文章目录


最近打算系统性的整理和分享AWS相关知识,而AWS CloudFormation这服务非常能提高你学习AWS的效率。所以先从这个服务开始介绍,后续我也会经常用到这个服务。

首先提醒一下,AWS CloudFormation需要你具有一定的AWS相关知识,比如在AWS Console上创建过VPC和EC2等资源,因为AWS CloudFormation这个服务,就是用代码的方式来创建资源,如果你不会通过图形化的方式创建,那么很难通过代码的方式来理解。

一、为什么需要AWS CloudFormation服务

利用AWS CloudFormation服务,可以让你通过代码的方式来创建AWS资源,这是AWS的基础架构即代码服务(IaC)。

为什么不在AWS Console界面来创建、删除资源,而是通过代码的方式来操作资源,主要有下面几个优势:

  1. 容易分享AWS环境给他人。通过代码的方式分享你的AWS环境,可以确保每次部署都是完全相同的,不用担心一些误操作引起的环境差异。当你需要学习一个新的服务时,经常会看到别人已经搭建好了所有的测试环境,并且分享了CloudFormation的代码,学会看这些代码能帮你提高学习效率。例如学习GWLB时看到这篇文档[参考链接1],节约了很多部署环境的时间。
  2. 可以「批量」操作AWS资源。在AWS CloudFormation代码里面,定义的VPC和EC2等这些资源,形成了一个堆栈(stack),创建或者删除一堆栈,就会自动创建或删除堆栈里面定义的所有资源。这个特点太方便学习做实验了,需要时,一键创建所有实验环境,做完后,一键打扫战场。避免漏删资源而扣费。
  3. 可以做版本控制。因为AWS CloudFormation都是代码文件,所以可以使用Git来进行版本控制。

二、AWS CloudFormation 模板格式

CloudFormation 模板就是你需要写的代码文件,模板是JSONYAML格式的文本文件,你可以指定任何的扩展名称,例如.txt,后缀名并不会影响内容的读取。

下面是在模板里面定义创建一个VPC,分别用JSON和YAML格式来展现。JSON和YAML格式是可以相互转换的,但是YAML支持注释功能,所以我更习惯使用YAML格式来写模板,之后的CloudFormation模板的代码我都会使用YAML格式来写。

通过JSON格式来创建一个VPC的代码,不用关心代码里面的字段,后面会讲解。

"MyTestVpc" : {
   "Type" : "AWS::EC2::VPC",
   "Properties" : {
      "CidrBlock" : "10.0.0.0/16",
      "EnableDnsSupport" : "true",
      "EnableDnsHostnames" : "true",
      "Tags" : [ 
         {"Key" : "Name", "Value" : "MyTestVpc"} 
      ]
   }
}

通过YAML格式来创建一个VPC的代码。YAML格式写起来更加简单,你可以写单引号、双引号、不写引号,都是一样的。我一般不写引号,除非字符较多,会通过引号来分隔字符。YAML和Python语法一样,不同的层级,通过缩进来区分。

# 创建VPC
MyTestVpc:
  Type: AWS::EC2::VPC
  Properties:
    CidrBlock: 10.0.0.0/16
    EnableDnsSupport: true
    EnableDnsHostnames: true
    Tags:
     - Key: Name
       Value: MyTestVpc

三、AWS CloudFormation 模板字段

下面是CloudFormation模板的所有字段,这是快速入门,只介绍最重要的一个字段,其他参考大家可以自己看文档模板格式[参考链接2],以后在其他文章中会陆续介绍这些参数。

Resources:这是唯一的必选字段,定义模板要创建哪些资源,例如创建VPC、EC2等,模板的主要作用就是定义资源,模板里面其他字段都可以省略,但是必须定义资源字段。

---
AWSTemplateFormatVersion: "version date"

Description:
  String

Metadata:
  template metadata

Parameters:
  set of parameters

Rules:
  set of rules

Mappings:
  set of mappings

Conditions:
  set of conditions

Transform:
  set of transforms

Resources:
  set of resources

Outputs:
  set of outputs

四、AWS CloudFormation 资源字段属性

4.1、实战案例

首先来看最重要的Resources字段,这个字段下面会有很多属性,而且不同的服务类型,属性参数并不一样。这些属性不需要你刻意去记忆, 主要还是明确需求之后,去查看文档资源和属性类型参考[参考链接3]。

这里通过一个实际的需求来看如何写CloudFormation的模板:创建一个VPC,内部创建一个EC2实例并关联安全组,实例通过IGW访问互联网。

4.2、创建VPC

创建一个VPC,查询VPC这个资源有哪些属性字段,AWS::EC2::VPC[参考链接4]

MyTestVpc是我起的一个名字,称为逻辑ID,注意命名不能有中横线和下划线。

AWS::EC2::VPC表示创建的资源类型。资源类型标识符采用这个格式:service-provider::service-name::data-type-name

10.0.0.0/16是为VPC分配的CIDR地址段,这是一个必选属性。创建一个资源时,脑海里面可以回顾AWS Console的操作,一般控制台界面必选的参数,在CloudFormation模板里面也会是必选。如果你需要修改某些特殊属性,但是不知道属性名称,那就需要查看文档了。

Tags标签参数应该不会陌生,因为可以添加多个标签,-表示列表,可以添加多个标签。

# 创建一个VPC
  MyTestVpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
      Tags:
       - Key: Name
         Value: MyTestVpc

4.3、创建IGW并关联到VPC

创建IGW并且关联到VPC:AWS::EC2::InternetGateway[参考链接5]

这里创建了一个IGW并且关联到了上面创建的VPC。将IGW关联到VPC时,用到了Ref这个函数。Ref内部函数[参考链接6]可以返回指定的参数资源的值。例如你需要查看AWS::EC2::VPC[参考链接4]就可以知道,它返回的是VpcId信息。

这里使用了Ref函数的短格式写法,可以写在一行!Ref logicalName,第二部分会专门介绍各种函数的用法。

# 创建IGW
  MyTestIgw:
    Type: "AWS::EC2::InternetGateway"
    Properties:
      Tags:
        - Key: Name
          Value: my-test-igw

# IGW 关联VPC
  MyTestAttachIgw:
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties:
      VpcId: !Ref MyTestVpc
      InternetGatewayId: !Ref MyTestIgw

4.4、创建子网

在VPC里面创建子网:AWS::EC2::Subnet[参考链接7]

这里子网需要指定VpcId,可以使用Ref内部函数来获取这个信息。

# 在VPC内创建子网
  MyTestVpcSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyTestVpc
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: cn-northwest-1a
      Tags:
      - Key: Name
        Value: my-test-vpc-public-subnet

4.5、路由表操作

在VPC内创建路由表并关联到子网,路由表设置默认路由指向IGW:AWS::EC2::RouteTable、AWS::EC2::Route、AWS::EC2::SubnetRouteTableAssociation

# VPC内创建路由表
  MyTestPublicRouteTable:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref IpsecTsVpc
      Tags:
        - Key: Name
          Value: my-test-public-route-table

# 路由表关联子网
  MyTestRouteTableAssociation:
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties:
      RouteTableId: !Ref MyTestPublicRouteTable
      SubnetId: !Ref MyTestVpcSubnet

# 路由表设置默认路由指向IGW
  MyTestInternetRoute:
    Type: "AWS::EC2::Route"
    Properties:
     RouteTableId: !Ref MyTestPublicRouteTable
     DestinationCidrBlock: 0.0.0.0/0
     GatewayId: !Ref MyTestIgw

4.6、创建安全组

在VPC内创建一个安全组:AWS::EC2::SecurityGroup

安全组里面数字-1表示允许所有。

# 在VPC内创建一个安全组
  MyTestVpcSg:
    Type: AWS::EC2::SecurityGroup
    DependsOn: MyTestVpc
    Properties:
      GroupDescription: SG to test ping
      VpcId: !Ref MyTestVpc
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 22
        ToPort: 22
        CidrIp: 0.0.0.0/0
      - IpProtocol: icmp
        FromPort: -1
        ToPort: -1
        CidrIp: 0.0.0.0/0
      - IpProtocol: tcp
        FromPort: 8443
        ToPort: 8443
        CidrIp: 0.0.0.0/0

4.7、创建EC2实例

创建一个EC2实例:AWS::EC2::Instance

指定了EC2的AMI ID,可以通过控制台查询AMI ID。需要确认账号下存在MyCN-CloudFormation-Test-Key这个密钥对信息。设置实例类型为t3.small。另外接口设置自动获取公网IP地址、因为是第一个主接口,所以编号为0、接口关联之前创建的安全组、接口放置之前创建的子网内。

# 创建一个EC2实例
  MyTestEc2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-003a3de8892ecbc45
      KeyName: MyCN-CloudFormation-Test-Key
      InstanceType: t3.small
      NetworkInterfaces:
        - AssociatePublicIpAddress: true
          DeviceIndex: 0
          GroupSet:
            - Ref: MyTestVpcSg
          SubnetId:  !Ref MyTestVpcSubnet

五、AWS 控制台创建堆栈(stack)

要将模板的代码实例化,就需要创建堆栈,可以通过AWS控制台、AWS CLI、API,来创建创建、更新、删除堆栈。模板里面所有的资源可以作为一个堆栈进行管理。

前面的内容单独解释每个资源如何创建,现在将这些资源都写到一个模板里面。这个模板中创建了一个VPC,VPC内部创建一个IGW,创建子网并将默认路由指向IGW。最后创建了一个EC2放置在公有子网里面,允许获取公网IP地址。

Resources:
# 创建一个VPC
  MyTestVpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
      Tags:
       - Key: Name
         Value: MyTestVpc

# 创建IGW
  MyTestIgw:
    Type: "AWS::EC2::InternetGateway"
    Properties:
      Tags:
        - Key: Name
          Value: my-test-igw
          
# IGW 关联VPC
  MyTestAttachIgw:
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties:
      VpcId: !Ref MyTestVpc
      InternetGatewayId: !Ref MyTestIgw

# 在VPC内创建子网
  MyTestVpcSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyTestVpc
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: cn-northwest-1a
      Tags:
      - Key: Name
        Value: my-test-vpc-public-subnet

# VPC内创建路由表
  MyTestPublicRouteTable:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref MyTestVpc
      Tags:
        - Key: Name
          Value: my-test-public-route-table

# 路由表关联子网
  MyTestRouteTableAssociation:
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties:
      RouteTableId: !Ref MyTestPublicRouteTable
      SubnetId: !Ref MyTestVpcSubnet

# 路由表设置默认路由指向IGW
  MyTestInternetRoute:
    Type: "AWS::EC2::Route"
    Properties:
     RouteTableId: !Ref MyTestPublicRouteTable
     DestinationCidrBlock: 0.0.0.0/0
     GatewayId: !Ref MyTestIgw

# 在VPC内创建一个安全组
  MyTestVpcSg:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: SG to test ping
      VpcId: !Ref MyTestVpc
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 22
        ToPort: 22
        CidrIp: 0.0.0.0/0
      - IpProtocol: icmp
        FromPort: -1
        ToPort: -1
        CidrIp: 0.0.0.0/0
      - IpProtocol: tcp
        FromPort: 8443
        ToPort: 8443
        CidrIp: 0.0.0.0/0
        
# 创建一个EC2实例
  MyTestEc2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-003a3de8892ecbc45
      KeyName: MyCN-CloudFormation-Test-Key
      InstanceType: t3.small
      NetworkInterfaces:
        - AssociatePublicIpAddress: true
          DeviceIndex: 0
          GroupSet:
            - Ref: MyTestVpcSg
          SubnetId:  !Ref MyTestVpcSubnet

进入AWS CloudFormation控制台,点击创建堆栈,选择使用新资源创建。

选择模板已就绪,上传准备的yaml文件,文件最大支持1MB,AWS会自动创建一个S3桶来存储模板文件。你也可以将模板文件上传到上s3,然后指定s3的路径来调用模板。

通过Designer你可以以图形化的方式来创建、查看和修改模板。我觉得这个Designer做的并不是很直观,仅供参考一下吧。

最后设置堆栈的名称,注意堆栈名称不能有下划线,可以有中横线。

通过【事件】可以查看堆栈创建的进度,如果堆栈创建失败,通过事件输出信息,可以非常容易的定位错误原因。

例如这里我故意将子网的AZ信息写成cn-northwest-1,少写了一个a。可以通过【事件】来查看报错信息,状态原因非常明确的说明了错误原因,你可以快速的根据“逻辑ID”来定位是哪个资源有错误,因为逻辑ID就是模板内的资源名称。

另外,当堆栈创建失败的时候,堆栈会自动回滚,将前面所有创建的资源都会删除,全都删除完成后,堆栈状态为ROLLBACK_COMPLETE,此时可以删除堆栈重新在创建一次。

将AZ信息修改正确后重新部署成功。

查看创建的VPC

查看创建的EC2和安全组

目前已经了解了AWS CloudFormation是如何工作的,有了一个快速了解,后续会继续介绍CloudFormation的内部函数。

六、参考文档

  • **[1] aws-gateway-load-balancer-code-samples:**https://github.com/aws-samples/aws-gateway-load-balancer-code-samples/tree/main/aws-cloudformation/centralized_architecture

  • **[2] AWS 模板格式:**https://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/template-anatomy.html

  • **[3] AWS 资源和属性类型参考:**https://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html

  • [4] AWS CloudFormation AWS::EC2::VPC:https://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html

  • **[5] AWS CloudFormation AWS::EC2::InternetGateway:**https://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internetgateway.html

  • **[6] AWS Ref 内部函数:**https://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html

  • **[7] AWS CloudFormation AWS::EC2::Subnet:**https://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html

有关AWS CloudFormation 系列--(1)快速入门的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  3. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  4. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  5. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  6. 阿里云RDS——产品系列概述 - 2

    基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于

  7. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  8. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  9. ruby - 如何以表格格式快速打印 Ruby 哈希值? - 2

    有没有办法快速将表格格式的ruby​​哈希打印到文件中?如:keyAkeyBkeyC...1232343451253474456...其中散列的值是不同大小的数组。还是使用双循环是唯一的方法?谢谢 最佳答案 试试我写的这个gem(在表中打印散列、ruby对象、ActiveRecord对象):http://github.com/arches/table_print 关于ruby-如何以表格格式快速打印Ruby哈希值?,我们在StackOverflow上找到一个类似的问题:

  10. ruby - 从结束值创建一系列字符串 - 2

    我使用irb。下面是我写的代码。“斧头”..“bc”我期待"ax""ay""az""ba"bb""bc"但结果只是“斧头”..“bc”我该如何纠正?谢谢。 最佳答案 >puts("ax".."bc").to_aaxayazbabbbc 关于ruby-从结束值创建一系列字符串,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7617092/

随机推荐