Запуск AWS CloudFormation через CLI + примеры использования (шаблон и ресурсы)

AWS CloudFormation — это «бесплатный» сервис, который помогает нам предоставлять и управлять ресурсами AWS только с помощью шаблона. Одно из преимуществ, которое мне нравится — нам не нужно искать, какие модули еще можно использовать, а какие уже устарели, потому что AWS предоставляет полную информацию в документации, нажмите здесь. Все, что нам нужно определить в шаблоне, предоставлено там. Одна из самых важных вещей об этой услуге, которую вы должны помнить: мы можем бесплатно использовать сервис CloudFormation, но вам будет выставлен счет за все услуги, созданные с помощью стека (те, которые вы определите в шаблоне).

Итак, мы будем делать все с CloudFormation через AWS CLI. Итак, убедитесь, что вы установили AWS CLI и настроили учетные данные. Если у вас все готово, давайте начнем!

1. Создайте шаблон
В первой версии шаблона я хочу создать S3 bucket с включенной версионностью. Я подготовил это для следующего шага, потому что когда мы создаем стек, загружая шаблон (хранящийся локально) через CLI, он не показывает нам, где он будет храниться (я расскажу вам об этом через секунду ниже).
Итак, я назвал шаблон cfn-demo.yaml, и он будет выглядеть следующим образом:

Resources:
  S3Bucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: cfn-bucket-template
      VersioningConfiguration:
        Status: Enabled
Вход в полноэкранный режим Выйти из полноэкранного режима

2. Создание стека
Как я уже говорил выше, когда мы создаем стек, загружая шаблон (хранящийся локально) через CLI, он не показывает нам, где он будет храниться. Совсем другое дело, когда мы создаем стек путем загрузки файла через консоль, который будет храниться в S3 bucket, сгенерированном самим CloudFormation, но этот bucket не будет удален, даже если стек был удален.




Тогда, чтобы предотвратить удаление не удаленного ведра из стека. Мы сначала создадим ведро, загрузим шаблон в ведро и будем использовать объект в качестве источника шаблона. Я просто хочу дать вам понять, что мы можем это сделать.

Давайте создадим стек!

$ aws cloudformation create-stack --stack-name cfn-demo --template-body file://cfn-demo.yaml
{
    "StackId": "arn:aws:cloudformation:ap-southeast-3:01234567890:stack/cfn-demo/2953bb10-ced2-11ec-a796-06bb617a2d70"
}
Вход в полноэкранный режим Выход из полноэкранного режима

Пожалуйста, подождите, пока статус не будет завершен.

$ aws cloudformation describe-stacks --stack-name cfn-demo
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:ap-southeast-3:01234567890:stack/cfn-demo/2953bb10-ced2-11ec-a796-06bb617a2d70",
            "StackName": "cfn-demo",
            "CreationTime": "2022-05-08T13:24:17.386Z",
            "RollbackConfiguration": {},
            "StackStatus": "CREATE_COMPLETE",
            "DisableRollback": false,
            "NotificationARNs": [],
            "Tags": [],
            "EnableTerminationProtection": false,
            "DriftInformation": {
                "StackDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}
Войти в полноэкранный режим Выход из полноэкранного режима

Давайте проверим ведро S3! Оно было создано или нет?

$ aws s3 ls
2022-05-08 20:24:45 cfn-bucket-template
Войти в полноэкранный режим Выйти из полноэкранного режима

3. Обновление стека
Чтобы обновить стек, нам нужно выполнить несколько шагов по сценарию. К ним относятся:

  • Внесите любые изменения в шаблон. В данном случае я создам дополнительные ресурсы (VPC, подсеть, интернет-шлюз, таблицу маршрутов, 2 группы безопасности и экземпляр EC2).
  • Загрузите вторую версию шаблона в ведро S3.
  • Обновите стек, используя объект S3 в качестве источника шаблона.

cfn-demo.yaml (вторая версия)

AWSTemplateFormatVersion: 2010-09-09

Parameters:
  EC2Type:
    Description: Type of instance
    Type: String
    Default: t3.micro
    AllowedValues:
    - t3.micro
    - t3.small
    - t3.medium
    - t3.large

Resources:
  S3Bucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: cfn-bucket-template
      VersioningConfiguration:
        Status: Enabled
  VirtualPrivateCloud:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 172.16.0.0/16
      Tags:
      - Key: "Name"
        Value: "CFN VPC"
  Subnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VirtualPrivateCloud
      CidrBlock: 172.16.1.0/28
      AvailabilityZone: ap-southeast-3a
      Tags:
      - Key: "Name"
        Value: "CFN Subnet"
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
      - Key: "Name"
        Value: "CFN IGW"
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VirtualPrivateCloud
      InternetGatewayId: !Ref InternetGateway
  RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VirtualPrivateCloud
      Tags:
      - Key: "Name"
        Value: "CFN Route"
  Route:
    Type: AWS::EC2::Route
    Properties: 
      RouteTableId: !Ref RouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  SubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref Subnet 
      RouteTableId: !Ref RouteTable
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupDescription: Allow SSH HTTP
      SecurityGroupIngress:
      - CidrIp: 0.0.0.0/0
        IpProtocol: tcp
        FromPort: 22
        ToPort: 22
      - CidrIp: 0.0.0.0/0
        IpProtocol: tcp
        FromPort: 80
        ToPort: 80
      VpcId: !Ref VirtualPrivateCloud
      Tags:
      - Key: "Name"
        Value: "CFN SG"
  SecurityGroup2:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupDescription: Only Allow SSH
      SecurityGroupIngress:
      - CidrIp: 0.0.0.0/0
        IpProtocol: tcp
        FromPort: 22
        ToPort: 22
      VpcId: !Ref VirtualPrivateCloud
      Tags:
      - Key: "Name"
        Value: "CFN SG2"
  KeyPair:
    Type: AWS::EC2::KeyPair
    Properties:
      KeyName: ec2-user
      PublicKeyMaterial: ssh-rsa VWXYZ.....(your pubkey goes here)
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref EC2Type
      AvailabilityZone: ap-southeast-3a
      ImageId: "ami-021fb2b73ff1efc96"
      KeyName: "ec2-user"
      BlockDeviceMappings:
      - DeviceName: "/dev/xvda"
        Ebs:
          DeleteOnTermination: "true"
          VolumeSize: "8"
          VolumeType: "gp2"
      NetworkInterfaces:
      - AssociatePublicIpAddress: "true"
        DeleteOnTermination: "true"
        DeviceIndex: 0
        SubnetId: !Ref Subnet
        GroupSet: 
          - Ref: SecurityGroup2
      UserData:
        Fn::Base64:
          !Sub |
            #!/bin/bash
            yum update -y
            yum install -y httpd
            systemctl enable httpd
            systemctl start httpd
      Tags:
      - Key: "Name"
        Value: "CFN Instance"

Outputs:
  EC2IpAddress:
    Description: "EC2 Public IP Address"
    Value: !GetAtt EC2Instance.PublicIp
Вход в полноэкранный режим Выход из полноэкранного режима

Загрузите файл в ведро S3 с помощью функции копирования:

$ aws s3 cp cfn-demo.yaml s3://cfn-bucket-template
upload: ./cfn-demo.yaml to s3://cfn-bucket-template/cfn-demo.yaml
$ aws s3 ls s3://cfn-bucket-template
2022-05-08 20:31:46       4256 cfn-demo.yaml
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем обновим стек, используя URL объекта S3 в качестве источника шаблона.

$ aws cloudformation update-stack --stack-name cfn-demo --template-url https://cfn-bucket-template.s3.ap-southeast-3.amazonaws.com/cfn-demo.yaml
{
    "StackId": "arn:aws:cloudformation:ap-southeast-3:01234567890:stack/cfn-demo/2953bb10-ced2-11ec-a796-06bb617a2d70"
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Пожалуйста, подождите, пока статус не будет завершен, и мы получим результат.

$ aws cloudformation describe-stacks --stack-name cfn-demo
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:ap-southeast-3:0123456789:stack/cfn-demo/2953bb10-ced2-11ec-a796-06bb617a2d70",
            "StackName": "cfn-demo",
            "Parameters": [
                {
                    "ParameterKey": "EC2Type",
                    "ParameterValue": "t3.micro"
                }
            ],
            "CreationTime": "2022-05-08T13:24:17.386Z",
            "LastUpdatedTime": "2022-05-08T13:33:13.916Z",
            "RollbackConfiguration": {},
            "StackStatus": "UPDATE_COMPLETE",
            "DisableRollback": false,
            "NotificationARNs": [],
            "Outputs": [
                {
                    "OutputKey": "EC2IpAddress",
                    "OutputValue": "108.136.169.98",
                    "Description": "EC2 Public IP Address"
                }
            ],
            "Tags": [],
            "EnableTerminationProtection": false,
            "DriftInformation": {
                "StackDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}
Вход в полноэкранный режим Выход из полноэкранного режима

Проверим порт экземпляра EC2, зайдя на него через SSH и веб-браузер.

$ ssh ec2-user@108.136.169.98 

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-172-16-1-8 ~]$ exit
logout
Connection to 108.136.169.98 closed.
Вход в полноэкранный режим Выход из полноэкранного режима

Почему мы проверяем порты? Потому что мы создали 2 группы безопасности и уже использовали первую для нашего экземпляра EC2. Теперь давайте внесем изменения в шаблон и снова загрузим его в ведро S3. В результате этого действия у нас будет две версии объекта (шаблона, который хранится в ведре S3).

До (чтобы разрешить SSH и HTTP):

        GroupSet: 
          - Ref: SecurityGroup
Войти в полноэкранный режим Выход из полноэкранного режима

После (чтобы разрешить только SSH):

        GroupSet: 
          - Ref: SecurityGroup2
Войти в полноэкранный режим Выйдите из полноэкранного режима

Затем, загрузите этот файл!

$ aws s3 cp cfn-demo.yaml s3://cfn-bucket-template
upload: ./cfn-demo.yaml to s3://cfn-bucket-template/cfn-demo.yaml
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь давайте снова обновим стек, используя URL объекта S3 в качестве источника шаблона!
(Будет использоваться самая новая версия шаблона)

$ aws cloudformation update-stack --stack-name cfn-demo --template-url https://cfn-bucket-template.s3.ap-southeast-3.amazonaws.com/cfn-demo.yaml
{
    "StackId": "arn:aws:cloudformation:ap-southeast-3:0123456789:stack/cfn-demo/2953bb10-ced2-11ec-a796-06bb617a2d70"
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Выход:

$ aws cloudformation describe-stacks --stack-name cfn-demo
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:ap-southeast-3:0123456789:stack/cfn-demo/2953bb10-ced2-11ec-a796-06bb617a2d70",
            "StackName": "cfn-demo",
            "Parameters": [
                {
                    "ParameterKey": "EC2Type",
                    "ParameterValue": "t3.micro"
                }
            ],
            "CreationTime": "2022-05-08T13:24:17.386Z",
            "LastUpdatedTime": "2022-05-08T13:40:42.678Z",
            "RollbackConfiguration": {},
            "StackStatus": "UPDATE_COMPLETE",
            "DisableRollback": false,
            "NotificationARNs": [],
            "Outputs": [
                {
                    "OutputKey": "EC2IpAddress",
                    "OutputValue": "108.136.160.193",
                    "Description": "EC2 Public IP Address"
                }
            ],
            "Tags": [],
            "EnableTerminationProtection": false,
            "DriftInformation": {
                "StackDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}
Вход в полноэкранный режим Выход из полноэкранного режима

Хотя мы меняем только группу безопасности, но через стек он заменит экземпляр EC2 на новый. Поэтому, возможно, это может быть обзор для нас, чтобы выбрать, что будет выполняться через CloudFormation или другими способами, скажем, вручную, может быть, через консоль, CLI, или что-то еще. Здесь я просто покажу вам основные моменты, когда мы используем CloudFormation через CLI и используем S3 для хранения шаблона.

Хорошо, давайте продолжим проверку! Текущий экземпляр должен быть доступен только через SSH.

$ telnet 108.136.160.193 80
Trying 108.136.160.193...
^C
$ ssh ec2-user@108.136.160.193

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-172-16-1-12 ~]$ exit
logout
Connection to 108.136.160.193 closed.
Войти в полноэкранный режим Выйдите из полноэкранного режима

Все работает! Теперь я хочу сделать еще одно изменение, но я буду использовать только первую (самую старую) версию объекта, не внося никаких изменений в шаблон. Я просто хочу вернуться назад, создав новый экземпляр, используя первую группу безопасности, которая разрешает SSH и HTTP. Это одно из преимуществ использования версионности S3 для хранения шаблона.

Получите идентификатор версии, а я возьму нижнюю!

$ aws s3api list-object-versions --bucket cfn-bucket-template --query 'Versions[].[Key, VersionId]'
[
    [
        "cfn-demo.yaml",
        "vtPszUgfpn8S9VZj5r6uHWKYL9HSlDRV"
    ],
    [
        "cfn-demo.yaml",
        "0DY8PO_LdRI_1WcppeMBSFc_ey5Djuxf"
    ]
]
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь давайте сделаем последнее обновление стека, используя URL объекта S3 в качестве источника шаблона! Пожалуйста, не забудьте указать ID версии, добавив ?versionId=xxx сразу после URL объекта.

$ aws cloudformation update-stack --stack-name cfn-demo --template-url https://cfn-bucket-template.s3.ap-southeast-3.amazonaws.com/cfn-demo.yaml?versionId=0DY8PO_LdRI_1WcppeMBSFc_ey5Djuxf
{
    "StackId": "arn:aws:cloudformation:ap-southeast-3:01234567890:stack/cfn-demo/2953bb10-ced2-11ec-a796-06bb617a2d70"
}
Вход в полноэкранный режим Выход из полноэкранного режима

Выход:

$ aws cloudformation describe-stacks --stack-name cfn-demo
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:ap-southeast-3:0123456789:stack/cfn-demo/2953bb10-ced2-11ec-a796-06bb617a2d70",
            "StackName": "cfn-demo",
            "Parameters": [
                {
                    "ParameterKey": "EC2Type",
                    "ParameterValue": "t3.micro"
                }
            ],
            "CreationTime": "2022-05-08T13:24:17.386Z",
            "LastUpdatedTime": "2022-05-08T13:49:09.816Z",
            "RollbackConfiguration": {},
            "StackStatus": "UPDATE_COMPLETE",
            "DisableRollback": false,
            "NotificationARNs": [],
            "Outputs": [
                {
                    "OutputKey": "EC2IpAddress",
                    "OutputValue": "108.136.160.169",
                    "Description": "EC2 Public IP Address"
                }
            ],
            "Tags": [],
            "EnableTerminationProtection": false,
            "DriftInformation": {
                "StackDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}
Вход в полноэкранный режим Выход из полноэкранного режима

Затем HTTP-порт нашего нового экземпляра EC2 должен быть открыт обратно.

4. Удаление шаблона
Мы загрузили 2 версии шаблона в ведро S3. Поэтому нам нужно удалить версии объектов перед удалением стека, так как мы загружаем файлы вручную (они не включены в стек).

$ aws s3api delete-object --bucket cfn-bucket-template --key cfn-demo.yaml --version-id vtPszUgfpn8S9VZj5r6uHWKYL9HSlDRV
{
    "VersionId": "vtPszUgfpn8S9VZj5r6uHWKYL9HSlDRV"
}
$ aws s3api delete-object --bucket cfn-bucket-template --key cfn-demo.yaml --version-id 0DY8PO_LdRI_1WcppeMBSFc_ey5Djuxf
{
    "VersionId": "0DY8PO_LdRI_1WcppeMBSFc_ey5Djuxf"
}
Вход в полноэкранный режим Выйдите из полноэкранного режима

5. Удалить стек
Теперь ведро пусто, и мы готовы удалить стек.

$ aws cloudformation delete-stack --stack-name cfn-demo
$ aws cloudformation describe-stacks --stack-name cfn-demo

An error occurred (ValidationError) when calling the DescribeStacks operation: Stack with id cfn-demo does not exist
Войти в полноэкранный режим Выход из полноэкранного режима

Вот и все. Мы уже дошли до конца этой статьи.
Что мы сделали?

  1. Создали шаблон CloudFormation со следующими задачами:
    • Создать S3 Bucket
    • Создать EC2 (VPC, подсеть, интернет-шлюз, таблицу маршрутизации, группу безопасности и экземпляр EC2).
  2. Создание, обновление и удаление стека CloudFormation через AWS CLI
  3. Загрузить объект в ведро S3 через AWS CLI
  4. Удаление версии объекта S3 через AWS CLI
  5. Используйте 2 разных источника шаблонов CloudFormation — локальный файл и S3 URL.

Вот и все! Спасибо, что пришли, и я с нетерпением жду ваших отзывов. Следите за мной, чтобы получать уведомления о публикации новых статей!

Оцените статью
Procodings.ru
Добавить комментарий