Cloudformation là gì

Nội dung

Trong bài thực hành Virtual Private Cloud, chúng ta sử dụng AWS CLI để cài đặt EC2 Instance và PostgreSQL Server trong Subnets của một VPC theo các bước sau:

  • Khai báo VPC và Subnets
  • Tạo Internet Gateway và liên kết với VPC
  • Tạo và cấu hình Route Table, Public Subnet
  • Cài đặt EC2 Instance trong Public Subnet
  • Cài đặt DB Instance trong Private Subnet
  • Kết nối DB Instance từ EC2 Instance

Cách làm này có một số điểm hạn chế:

  • Câu lệnh CLI phức tạp, không có tính tái sử dụng
  • Sử dụng nhiều các giá trị tham số, dễ gặp sai sót
  • Không cung cấp cơ chế quản lý thay đổi, rollback

Để khắc phục điều này, AWS cung cấp dịch vụ CloudFormation cho phép chúng ta mô hình hoá và triển khai [provisioning] các tài nguyên AWS theo hướng tiếp cận Declarative. Với cách tiếp cận này, người sử dụng chỉ cần khai báo tài nguyên cùng các thuộc tính yêu cầu, cũng như mối quan hệ giữa các tài nguyên trong một file Template dưới định dạng dạng YAML hoặc JSON. Dựa trên thông tin khai báo, dịch vụ CloudFormation sẽ thực hiện việc gọi các AWS API để cấp phát và cấu hình tài nguyên theo mong muốn. Bên cạnh đó, tập hợp các tài nguyên này được quản lý bởi cùng một đối tượng Stack, cho phép người sử dụng dễ dàng nâng cấp, bổ sung những cấu hình mong muốn cũng như quản lý được mọi thay đổi trong quá trình cập nhật hay triển khai.

AWS Resource Provision Engines

Để thực hành CloudFormation, chúng ta sẽ bắt đầu với một cấu trúc template file đơn giản, từ đó bổ sung các thành phần cần thiết để xây dựng EC2 và DB Instances trong một VPC tương tự kết quả như kết quả thực hành từ bài viết Virtual Private Cloud.

Cài đặt VPC

  • Tạo template file rds.yaml

AWSTemplateFormatVersion: "2010-09-09" Description: Deploys a VPC with Subnets in differents Availability Zones. It deploys an EC2 Instance on Public Subnet and RDS PostgreSQL Instance on Private Subnets Parameters: VpcCIDR: Description: IP range [CIDR notation] for this VPC Type: String Default: "10.0.0.0/16" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCIDR EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: VPC Sample Outputs: StackVPC: Description: The ID of the VPC Value: !Ref VPC

  • Theo cấu trúc của một file CloudFormation Template, nội dung rds.yaml bao gồm các phần:
    • AWSTemplateFormatVersion: khai báo định dạng Template
    • Description: mô tả mục đích sử dụng của Template
    • Parameters: tham số khi tạo Stack với giá trị mặc định
    • Resources: tài nguyên cần tạo ra trong Stack, bao gồm:
      • VPC với giá trị thuộc tính CIdrBlock tham chiếu bởi Ref function
    • Outputs: kết quả hiển thị khi Stack hoàn thành
      • Trả về VPC ID tạo ra qua build-in function Ref
  • Triển khai CloudFormation Stack

Trong cùng folder chứa rds.yaml, thực hiện lệnh tạo Stack - rds-stack:

aws cloudformation create-stack --stack-name rds-stack --template-body file://rds.yaml

Output:

{ "StackId": "arn:aws:cloudformation:ap-southeast-2:729365137003:stack/rds-stack/4156e520-101a-11eb-ab18-0218c804214a" }

  • Sử dụng câu lệnh describe-stack kiểm tra kết quả từ Stack:

aws cloudformation describe-stacks --stack-name rds-stack

Output

{ "Stacks": [ { "StackId": "arn:aws:cloudformation:ap-southeast-2:729365137003:stack/rds-stack/4156e520-101a-11eb-ab18-0218c804214a", "StackName": "rds-stack", "Description": "Deploys a VPC with Subnets in differents Availability Zones. It deploys an EC2 Instance on Public Subnet and RDS PostgreSQL Instance on Private Subnets", "Parameters": [ { "ParameterKey": "VpcCIDR", "ParameterValue": "10.0.0.0/16" } ], "CreationTime": "2020-10-17T01:44:11.681000+00:00", "RollbackConfiguration": {}, "StackStatus": "CREATE_COMPLETE", "DisableRollback": false, "NotificationARNs": [], "Outputs": [ { "OutputKey": "StackVPC", "OutputValue": "vpc-0dcabb2e4dc217670", "Description": "The ID of the VPC" } ], "Tags": [], "EnableTerminationProtection": false, "DriftInformation": { "StackDriftStatus": "NOT_CHECKED" } } ] }

  • Sử dụng AWS Console, CloudFormation -> Stack để hiển thị kết quả Stacks:

CloudFormation Stack Overview

  • Click tab Outputs để kiểm tra kết quả trả về khi việc tạo Stack hoàn thành:

CloudFormation Stack Output with VPC ID

Dựa trên VPC đã tạo ra, trong phần này chúng ta sẽ bổ sung khai báo Subnets trong VPC. Các bước thực hiện bao gồm:

Bước 1: Cập nhật nội dung rds.yaml để bổ sung Subnets:

AWSTemplateFormatVersion: "2010-09-09" Description: Deploys a VPC with Subnets in differents Availability Zones. It deploys an EC2 Instance on Public Subnet and RDS PostgreSQL Instance on Private Subnets Parameters: VpcCIDR: Description: IP range [CIDR notation] for this VPC Type: String Default: "10.0.0.0/16" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" SubnetACidr: Description: Public Subnet of VPC Type: String Default: "10.0.0.0/24" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" SubnetBCidr: Description: Private Subnet of VPC Type: String Default: "10.0.1.0/24" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" SubnetCCidr: Description: Private Subnet of VPC Type: String Default: "10.0.2.0/24" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCIDR EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: VPC Sample SubnetA: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [0, !GetAZs ""] CidrBlock: !Ref SubnetACidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: Subnet A [AZ1] SubnetB: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [1, !GetAZs ""] CidrBlock: !Ref SubnetBCidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: Subnet B [AZ2] SubnetC: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [2, !GetAZs ""] CidrBlock: !Ref SubnetCCidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: Subnet C [AZ3] Outputs: StackVPC: Description: The ID of the VPC Value: !Ref VPC

  • Thay đổi này bao gồm các bổ sung:
    • Parameters: khai báo CIRD cho Subnets A, B, C cùng giá trị CIDR mặc định
    • Resources: yêu cầu tạo các Subnets bên trong VPC
      • Sử dụng Ref function để tham chiếu đến VPC và giá trị CIDR
      • Kết hợp Select & GetAZs để cài đặt Subnet trong những AZs khác nhau

Bước 2: Thực thi việc cập nhật thay đổi

Bằng cách sử dụng AWS CLI, CloudFormation cung cấp hai cách thức để thực thi quá trình thay đổi CloudFormation Stack:

  • Áp dụng trực tiếp lệnh ` aws cloudformation update-stack`
  • Tạo và thực thi Change Set

Process of Update by Change Set

Chú ý

Việc sử dụng Change Set giúp người dùng có thể xem xét trước nội dung thay đổi cũng như ảnh hưởng đến resources hiện tại khi thực thi những thay đổi này. Ví dụ: khi Stack đang quản lý một database, việc thay đổi giá trị một thuộc tính có khả năng dẫn đến việc xoá bỏ và tạo database mới, mất đi những dữ liệu hiện có. Bằng cách sử dụng change set, người dùng có thể đánh giá ảnh hưởng trước khi quyết định việc thực thi thay đổi.

Thực hiện tạo Change Set dựa trên cập nhật từ file rds.yaml:

aws cloudformation create-change-set \ --stack-name rds-stack \ --change-set-name rds-subnets-change-set \ --template-body file://rds.yml

Output

{ "Id": "arn:aws:cloudformation:ap-southeast-2:729365137003:changeSet/rds-subnets-change-set/80984f68-adca-4f0d-b70f-2a45f27d8ecc", "StackId": "arn:aws:cloudformation:ap-southeast-2:729365137003:stack/rds-stack/4156e520-101a-11eb-ab18-0218c804214a" }

Stack Change Set in AWS Console

  • Dựa trên Change Set Id, thực thi thay đổi với lệnh:

aws cloudformation execute-change-set --change-set-name arn:aws:cloudformation:ap-southeast-2:729365137003:changeSet/rds-subnets-change-set/80984f68-adca-4f0d-b70f-2a45f27d8ecc

  • Sử dụng AWS Console, xác nhận việc thực thi Change Set

Stack Change Set Execution

Stack Change Set Events

  • Trong hiển thị của rds-stack trên AWS Console, click tab Template để hiển thị nội dung Template hiện tại của Stack. Trên màn hình này, click button View in Designer cho phép chúng ta có được hiển thị trực quan các thành phần trong Stack hiện tại:

Stack in View Designer

Trong phần này, chúng ta tiếp tục bổ sung các thành phần Internet Gateway và Route Table cho phép các thành phần trong Subnet A có khả năng giao tiếp môi trường Internet [Public Subnet].

  • Nội dung cập nhật của CloudFormation Template rds.yaml:

AWSTemplateFormatVersion: "2010-09-09" Description: Deploys a VPC with Subnets in differents Availability Zones. It deploys an EC2 Instance on Public Subnet and RDS PostgreSQL Instance on Private Subnets Parameters: VpcCIDR: Description: IP range [CIDR notation] for this VPC Type: String Default: "10.0.0.0/16" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" SubnetACidr: Description: Public Subnet of VPC Type: String Default: "10.0.0.0/24" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" SubnetBCidr: Description: Private Subnet of VPC Type: String Default: "10.0.1.0/24" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" SubnetCCidr: Description: Private Subnet of VPC Type: String Default: "10.0.2.0/24" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCIDR EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: VPC Sample SubnetA: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [0, !GetAZs ""] CidrBlock: !Ref SubnetACidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: Subnet A [AZ1] SubnetB: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [1, !GetAZs ""] CidrBlock: !Ref SubnetBCidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: Subnet B [AZ2] SubnetC: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [2, !GetAZs ""] CidrBlock: !Ref SubnetCCidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: Subnet C [AZ3] InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: Internet Gateway InternetGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VPC PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: Public Route Table DefaultPublicRoute: Type: AWS::EC2::Route DependsOn: InternetGatewayAttachment Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway SubnetARouteTableAssoc: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PublicRouteTable SubnetId: !Ref SubnetA Outputs: StackVPC: Description: The ID of the VPC Value: !Ref VPC

  • Tóm tắt những nội dung thay đổi:
    • Khai báo và liên kết Internet Gateway với VPC
    • Tạo Custom Route Table và khai báo Route kết nối Internet Gateway
    • Liên kết SubnetA và Custom Route Table
  • Tạo Change Set với lệnh:

aws cloudformation create-change-set \ --stack-name rds-stack \ --change-set-name public-subnets-change-set \ --template-body file://rds.yml

Output

{ "Id": "arn:aws:cloudformation:ap-southeast-2:729365137003:changeSet/public-subnets-change-set/401a95e9-4dbd-4049-8609-1a654f27121c", "StackId": "arn:aws:cloudformation:ap-southeast-2:729365137003:stack/rds-stack/4156e520-101a-11eb-ab18-0218c804214a" }

Change Set for Public VPC

aws cloudformation execute-change-set --change-set-name arn:aws:cloudformation:ap-southeast-2:729365137003:changeSet/public-subnets-change-set/401a95e9-4dbd-4049-8609-1a654f27121c

VPC with Public Subnet in Designer

Để bổ sung EC2 Instance trong Public Subnet của VPC, thực hiện thay đổi sau trên rds.yaml:

AWSTemplateFormatVersion: "2010-09-09" Description: Deploys a VPC with Subnets in differents Availability Zones. It deploys an EC2 Instance on Public Subnet and RDS PostgreSQL Instance on Private Subnets Parameters: VpcCIDR: Description: IP range [CIDR notation] for this VPC Type: String Default: "10.0.0.0/16" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" SubnetACidr: Description: Public Subnet of VPC Type: String Default: "10.0.0.0/24" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" SubnetBCidr: Description: Private Subnet of VPC Type: String Default: "10.0.1.0/24" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" SubnetCCidr: Description: Private Subnet of VPC Type: String Default: "10.0.2.0/24" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" InstanceType: Description : WebServer EC2 instance type Type : String Default : t2.micro AllowedValues: - t2.micro - m1.small - m1.large Description: Enter t2.micro, m1.small, or m1.large. Default is t2.micro. Mappings: AWSRegionArch2AMI: us-east-1: HVM64: ami-0e7067c52e5fac7aa ap-southeast-2: HVM64: ami-0b007620b3c6fd7ff Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCIDR EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: VPC Sample SubnetA: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [0, !GetAZs ""] CidrBlock: !Ref SubnetACidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: Subnet A [AZ1] SubnetB: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [1, !GetAZs ""] CidrBlock: !Ref SubnetBCidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: Subnet B [AZ2] SubnetC: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [2, !GetAZs ""] CidrBlock: !Ref SubnetCCidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: Subnet C [AZ3] InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: Internet Gateway InternetGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VPC PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: Public Route Table DefaultPublicRoute: Type: AWS::EC2::Route DependsOn: InternetGatewayAttachment Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway SubnetARouteTableAssoc: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PublicRouteTable SubnetId: !Ref SubnetA EC2Instance: Type: AWS::EC2::Instance Properties: ImageId: !FindInMap [AWSRegionArch2AMI, !Ref "AWS::Region", HVM64] InstanceType: !Ref InstanceType SecurityGroupIds: - !Ref Ec2SecurityGroup SubnetId: !Ref SubnetA KeyName: FriendReminders UserData: Fn::Base64: !Sub | #!/bin/bash -xe sudo yum install -y amazon-linux-extras sudo amazon-linux-extras install postgresql11 Ec2SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VPC GroupDescription: Enable SSH access via port 22 SecurityGroupIngress: - CidrIp: 0.0.0.0/0 FromPort: 22 IpProtocol: tcp ToPort: 22 Outputs: StackVPC: Description: The ID of the VPC Value: !Ref VPC

  • Các nội dung thay đổi chú ý:
    • Parameters: bổ sung Instance Type tương ứng cấu hình phần cứng của EC2 Instance.
    • Mappings: khai báo mapping - AWSRegionArch2AMI. Mỗi giá trị key trong Map tương ứng với một tập hợp Mapping khác.
      • Key us-east-1: tương ứng Map giữa HVM64 và AMI ID
      • Key ap-southeast-2: tương ứng Map giữa HVM64 với AMI ID
    • Resources:
      • Security Group Ec2SecurityGroup cho phép truy cập SSH qua Port 22
      • EC2 Instance EC2Instance:
        • ImageId: sử dụng look-up function FindInMap trả về AMI ID tương ứng region
        • InstanceType: dựa trên tham số đưa vào, giá trị mặc định t2.micro
        • Liên kết với Security Group Ec2SecurityGroup dựa trên Ref function
        • Sử dụng UserData để thực hiện các cài đặt psql client trong quá trình khởi tạo

Hướng dẫn

Tập hợp các Name - Value trong Mapping thường được kết hợp với một Look-up function FindInMap trả về giá trị Value dựa trên tham số truyền vào. Trong ví dụ của EC2 Instance, tương ứng với mỗi AWS Region, function FindInMap sẽ trả về giá trị AMI tương ứng với Amazon Linux 2 AMI ID được tạo ra bởi Amazon trên Region đó.

  • Ngoài ra, để có được giá trị AMI ID cập nhật từ AWS theo từng region, chúng ta có thể sử dụng câu lệnh sau:

Hiển thị danh sách AMI ID của Amazon Linux theo region ap-southeast-2

aws ssm get-parameters-by-path --path /aws/service/ami-amazon-linux-latest --region ap-southeast-2

Trong ví dụ trên, chúng ta chỉ sử dụng tập hợp các giá trị AMI ID tương ứng với amzn-ami-hvm-x86_64-ebs. Đây là hệ điều hành Amazon Linux 2 sử dụng cơ chế ảo hoá phần cứng - Hardware Virtual Machine [HVM]. So với cơ chế ảo hoá song song - Paravirtual [PV], HVM đem lại hiệu năng cao hơn do khả năng tận dụng những khả năng mở rộng của phần cứng [CPU, Network, Storage].

  • Tạo và thực thi Change Set

aws cloudformation create-change-set \ --stack-name rds-stack \ --change-set-name public-subnets-change-set \ --template-body file://rds.yml

Output

{ "Id": "arn:aws:cloudformation:ap-southeast-2:729365137003:changeSet/ec2-change-set/cc5fd8d3-06be-4520-877a-4134e1fdc287", "StackId": "arn:aws:cloudformation:ap-southeast-2:729365137003:stack/rds-stack/4156e520-101a-11eb-ab18-0218c804214a" }

aws cloudformation execute-change-set --change-set-name arn:aws:cloudformation:ap-southeast-2:729365137003:changeSet/ec2-change-set/cc5fd8d3-06be-4520-877a-4134e1fdc287

VPC with Public Subnet / EC2 in Designer

  • Kiểm tra giá trị Public IP và kết nối đến EC2 Instance qua lệnh SSH

ssh -i "FriendReminders.pem"

  • Trên Terminal của EC2 Instance, xác nhận version cài đặt của psql

Cài đặt PostgreSQL Instance trong Private Subnets

  • Để bổ sung DB Instance trong Public Subnet của VPC, thực hiện thay đổi sau trên rds.yaml:

AWSTemplateFormatVersion: "2010-09-09" Description: Deploys a VPC with Subnets in differents Availability Zones. It deploys an EC2 Instance on Public Subnet and RDS PostgreSQL Instance on Private Subnets Parameters: VpcCIDR: Description: IP range [CIDR notation] for this VPC Type: String Default: "10.0.0.0/16" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" SubnetACidr: Description: Public Subnet of VPC Type: String Default: "10.0.0.0/24" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" SubnetBCidr: Description: Private Subnet of VPC Type: String Default: "10.0.1.0/24" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" SubnetCCidr: Description: Private Subnet of VPC Type: String Default: "10.0.2.0/24" AllowedPattern: "[[\\d{1,3}]\\.]{3}\\d{1,3}/\\d{1,2}" InstanceType: Description : WebServer EC2 instance type Type : String Default : t2.micro AllowedValues: - t2.micro - m1.small - m1.large DBInstanceIdentifier: Type: String Default: "dbpostgresql" DBEngine: Type: String Default: "postgres" DBEngineVersion: Type: String Default: "12.3" DBSourceRegion: Type: String Default: "ap-southeast-2" DBInstanceClass: Type: String Default: "db.t2.micro" DBStorageType: Type: String Default: "gp2" DBAllocatedStorage: Type: Number Default: 20 DBName: Type: String Default: "postgres" DBUser: Type: String Default: "postgres" DBPassword: Type: String Default: "password" NoEcho: True Mappings: AWSRegionArch2AMI: us-east-1: HVM64: ami-0e7067c52e5fac7aa ap-southeast-2: HVM64: ami-0b007620b3c6fd7ff Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCIDR EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: VPC Sample SubnetA: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [0, !GetAZs ""] CidrBlock: !Ref SubnetACidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: Subnet A [AZ1] SubnetB: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [1, !GetAZs ""] CidrBlock: !Ref SubnetBCidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: Subnet B [AZ2] SubnetC: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [2, !GetAZs ""] CidrBlock: !Ref SubnetCCidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: Subnet C [AZ3] DBSubnetGroup: Properties: DBSubnetGroupDescription: DBSubnetsGroup for RDS instances SubnetIds: - Ref: SubnetB - Ref: SubnetC Type: AWS::RDS::DBSubnetGroup InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: Internet Gateway InternetGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VPC PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: Public Route Table DefaultPublicRoute: Type: AWS::EC2::Route DependsOn: InternetGatewayAttachment Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway SubnetARouteTableAssoc: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PublicRouteTable SubnetId: !Ref SubnetA Ec2SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VPC GroupDescription: Enable SSH access via port 22 SecurityGroupIngress: - CidrIp: 0.0.0.0/0 FromPort: 22 IpProtocol: tcp ToPort: 22 EC2Instance: Type: AWS::EC2::Instance Properties: ImageId: !FindInMap [AWSRegionArch2AMI, !Ref "AWS::Region", HVM64] InstanceType: !Ref InstanceType SecurityGroupIds: - !Ref Ec2SecurityGroup SubnetId: !Ref SubnetA KeyName: FriendReminders UserData: Fn::Base64: !Sub | #!/bin/bash -xe sudo yum install -y amazon-linux-extras sudo amazon-linux-extras install postgresql11 VpcDefaultSecurityGroupIngress: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: !GetAtt VPC.DefaultSecurityGroup SourceSecurityGroupId: !GetAtt Ec2SecurityGroup.GroupId IpProtocol: tcp FromPort: 5432 ToPort: 5432 DBInstance: Type: AWS::RDS::DBInstance Properties: DBInstanceIdentifier: Ref: DBInstanceIdentifier DBName: Ref: DBName AllocatedStorage: Ref: DBAllocatedStorage DBInstanceClass: Ref: DBInstanceClass StorageType: Ref: DBStorageType Engine: Ref: DBEngine EngineVersion: Ref: DBEngineVersion MasterUsername: Ref: DBUser MasterUserPassword: Ref: DBPassword PubliclyAccessible: False Tags: - Key: Project Value: "Demo of RDS PostgreSQL" VPCSecurityGroups: - !GetAtt VPC.DefaultSecurityGroup DBSubnetGroupName: Ref: DBSubnetGroup Outputs: StackVPC: Description: The ID of the VPC Value: !Ref VPC

  • Các nội dung thay đổi chú ý:
    • Parameters: bổ sung các tham số liên quan đến DB Instance [Identifier, Storage, etc…]
    • Resources:
      • Security Group Rule - VpcDefaultSecurityGroupIngress áp dụng cho VPC Security Group
      • DB Subnets Group - DBSubnetGroup sử dụng bởi PostgreSQL DB Instance
      • PostgreSQL DB Instance DBInstance:
        • VPCSecurityGroups: sử dụng VPC Security Group thông qua GetAtt function
        • DBSubnetGroupName: tham chiếu đến DB Subnets Group qua Ref function
  • Tạo và thực thi Change Set với nội dung thay đổi của rds.yaml file.

VPC with EC2 and DB Instances

Kết nối DB PostgreSQL từ EC2 Instance

  • Kết nối EC2 Instance qua SSH

ssh -i "FriendReminders.pem"

  • Kiểm tra kết quả DB Endpoint trên AWS Console

DB Endpoint URL

  • Sử dụng lệnh psql kiểm tra kết nối giữa EC2 Instance và PostgreSQL

psql -h dbpostgresql2.ctcnoszp8xta.ap-southeast-2.rds.amazonaws.com -U postgres

Kết luận

CloudFormation giúp việc cấu hình và triển khai AWS Resource hiệu quả hơn so với AWS CLI hoặc AWS Console. Bằng việc sử dụng Parameters và Output, CloudFormation Templates có tính tái sử dụng cao hơn, đồng thời người sử dụng có thể kết hợp nhiều templates khi muốn triển khai các cơ sở hạ tầng phức tạp.

Tài liệu tham khảo

  • Amazon Linux 2
  • Linux AMI virtualization types

Copyright © 2019-2022 Tuan Anh Le.

Video liên quan

Chủ Đề