Các nhà phát triển đã quen với việc sử dụng công cụ của riêng họ và viết bằng các ngôn ngữ quen thuộc. Trong nhiều năm, Ngôn ngữ cấu hình Hashicorp [HCL] là một trong những ngôn ngữ phát triển nhanh nhất tại GitHub, và chúng tôi thường nghe thấy mong muốn cung cấp cơ sở hạ tầng với các ngôn ngữ lập trình quen thuộc. Ngày nay, chúng tôi vui mừng thông báo bản xem trước cộng đồng của Bộ phát triển đám mây cho Hashicorp Terraform cho phép người dùng xác định cơ sở hạ tầng bằng cách sử dụng TypeScript và Python trong khi tận dụng hàng trăm nhà cung cấp và hàng ngàn định nghĩa mô -đun được cung cấp bởi Terraform và Terraform Ecosystem.
Chúng tôi đã hợp tác với nhóm AWS và nhóm phát triển đám mây [CDK] của họ để hỗ trợ dự án mới này tận dụng hai thành phần chính của AWS CDK: một bộ các khung bản địa ngôn ngữ để xác định cơ sở hạ tầng và bộ điều hợp cho một công cụ cung cấp cơ bản. Sử dụng các thư viện này, AWS CDK tạo cấu hình CloudFormation. Tương tự, CDK cho Terraform tạo ra cấu hình Terraform để cho phép cung cấp với Terraform. Bộ điều hợp hoạt động với bất kỳ nhà cung cấp và mô -đun hiện có nào được lưu trữ trong Cơ quan đăng ký Terraform. Quy trình công việc cốt lõi của Terraform vẫn giữ nguyên, với khả năng lập kế hoạch thay đổi trước khi áp dụng.
Bạn có thể sử dụng dự án này ngay hôm nay với bản phát hành ban đầu của chúng tôi. Chúng tôi đã tạo các ví dụ từng bước với hướng dẫn bắt đầu nhanh của Docker, AWS và các ví dụ khác trong Python và TypeScript.
»Terraform như một nền tảng
Mục tiêu của Terraform là cung cấp một quy trình làm việc nhất quán để cung cấp cơ sở hạ tầng. Terraform tuân theo một cơ sở hạ tầng khi cách tiếp cận mã và có thể mở rộng để hỗ trợ nhiều nhà cung cấp dịch vụ cơ sở hạ tầng và phần mềm của đám mây. Ưu điểm của mã hóa là khả năng tự động hóa việc tạo cơ sở hạ tầng, sử dụng quy trình làm việc theo điều khiển phiên bản, xem xét lại các thay đổi và sử dụng các thực tiễn tốt nhất về phát triển phần mềm.
Với việc giới thiệu hỗ trợ CDK cho Terraform, có nhiều cách hơn bao giờ hết để cung cấp và quản lý cơ sở hạ tầng với Terraform. Trong lịch sử, chúng tôi đã hỗ trợ HCL và JSON. Trong khi HCL có nghĩa là được đọc và viết bởi mọi người, JSON có nghĩa là được tạo ra và tiêu thụ bằng máy. Đầu năm nay, chúng tôi đã công bố hỗ trợ thử nghiệm cho các định nghĩa tài nguyên tùy chỉnh Kubernetes [CRDS] bằng toán tử Terraform. Điều này cho phép người dùng Kubernetes định cấu hình tài nguyên Terraform với quy trình làm việc bản địa của Kubernetes. Định nghĩa tài nguyên tùy chỉnh được dịch thành Terraform và được thực hiện từ xa bởi Terraform Cloud. Các doanh nghiệp truyền thống sử dụng phần mềm ITSM như ServiceNow có thể tích hợp với Terraform Enterprise để hỗ trợ cách tiếp cận dựa trên bán vé truyền thống hơn. Cuối cùng, với hỗ trợ CDK, các ngôn ngữ lập trình như Python và TypeScript có thể được sử dụng ngày hôm nay. Hỗ trợ ngôn ngữ bổ sung cho JavaScript, Java và C# có thể được sử dụng trong tương lai.
Điều này cho phép Terraform hoạt động như một nền tảng chung để cung cấp cơ sở hạ tầng và quản lý vòng đời. Ngày nay, có hàng trăm nhà cung cấp Terraform, bao gồm đám mây công cộng, đám mây riêng, phần cứng lưu trữ và mạng, dịch vụ đám mây, v.v. Người dùng Terraform có thể soạn thảo cơ sở hạ tầng của họ và mở rộng nó để hỗ trợ nhu cầu của họ một cách dễ dàng. Mục tiêu của chúng tôi là làm cho nó có thể truy cập nhất có thể để sử dụng Terraform và chúng tôi làm điều đó bằng cách cung cấp cho các giao diện mà người dùng tìm thấy thuận tiện nhất. Có một loạt các giao diện có sẵn ngày hôm nay và chúng tôi tiếp tục học hỏi từ cộng đồng và khách hàng của chúng tôi về nơi chúng tôi có thể cải thiện.
Mặc dù Terraform cung cấp nền tảng cốt lõi để cung cấp, chúng tôi đã xây dựng Terraform Cloud trên đầu để cung cấp nền tảng cốt lõi để hợp tác. Bằng cách cung cấp một nơi trung tâm để lưu trữ nhà nước, quản lý quyền, kích hoạt webhooks và thực thi chính sách, chúng tôi giúp các nhóm của hàng chục, hàng trăm hoặc hàng ngàn cộng tác trên cơ sở hạ tầng. Bằng cách hỗ trợ API và webhooks, chúng tôi giúp việc tích hợp Cloud Terraform với các hệ thống khác, chẳng hạn như GitHub, Gitlab, Circleci, v.v. Điều này cho phép bạn sử dụng Terraform Cloud như một phần của đường ống phân phối phức tạp hơn, nhưng vẫn duy trì khả năng hiển thị và kiểm soát.
Với Dự án CDK cho Terraform, bạn có thể xác định tài nguyên cơ sở hạ tầng bằng cách sử dụng các ngôn ngữ lập trình được hỗ trợ. Công cụ tạo ra cấu hình Terraform trong JSON có thể được áp dụng với
$ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
3 hoặc sử dụng CDK cho Terraform CLI với $ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
4. Nó hỗ trợ các ngôn ngữ polyglot bằng cách sử dụng các thư viện nền tảng mà AWS CDK dựa vào để tạo và tổng hợp cấu hình cơ sở hạ tầng.Dự án CDK cho Terraform bao gồm hai gói:
- CLI CDKTF -CLI - Một CLI cho phép người dùng chạy các lệnh để khởi tạo, nhập và tổng hợp CDK cho các ứng dụng Terraform.
- Cấm CDKTF - một thư viện để xác định tài nguyên Terraform bằng cách sử dụng các cấu trúc lập trình.
"Bắt đầu
Bản xem trước cộng đồng cho CDK cho Terraform bao gồm các tính năng cho phép người dùng quen thuộc với Terraform để viết các cấu trúc lập trình và tạo cấu hình Terraform trong các tệp JSON. Sử dụng CDK cho Terraform CLI để khởi tạo một dự án trong TypeScript hoặc Python.
Ví dụ để bắt đầu sử dụng TypeScript. Bắt đầu bằng cách cài đặt Node.js, sợi.
Tiếp theo, cài đặt CDK cho Terraform trên toàn cầu.
$ npm install -g cdktf-cli
»Khởi tạo một dự án mới
Tạo một thư mục để lưu trữ các tệp TypeScript để tạo AWS VPC. Khởi tạo một tập hợp các mẫu TypeScript bằng cách sử dụng
$ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
5.$ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
Nhập chi tiết liên quan đến dự án bao gồm Terraform Cloud để lưu trữ trạng thái dự án. Bạn có thể sử dụng tùy chọn
$ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
6 để tiếp tục mà không cần sử dụng Terraform Cloud để quản lý nhà nước.We will now setup the project. Please enter the details for your project.
If you want to exit, press ^C.
Project Name: [default: 'vpc-example']
Project Description: [default: 'A simple getting started project for cdktf.']
Một số bước xảy ra khi chạy
$ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
5. Lệnh:- Tải xuống một dự án mẫu với mẫu được chỉ định, được xác định trong
8.$ mkdir vpc-example $ cd vpc-example $ cdktf init --template=typescript
- Định cấu hình Tổ chức đám mây Terraform và không gian làm việc nếu được chỉ định.
- Chạy
9 để tải xuống các nhà cung cấp và mô -đun Terraform thích hợp. Trong ví dụ này, nó tải xuống nhà cung cấp AWS được chỉ định trong$ mkdir vpc-example $ cd vpc-example $ cdktf init --template=typescript
0.We will now setup the project. Please enter the details for your project. If you want to exit, press ^C. Project Name: [default: 'vpc-example'] Project Description: [default: 'A simple getting started project for cdktf.']
- Tạo các đối tượng dành riêng cho ngôn ngữ cho các tài nguyên và mô-đun trong thư mục
1 dựa trên các lược đồ của nhà cung cấp và mô-đun.We will now setup the project. Please enter the details for your project. If you want to exit, press ^C. Project Name: [default: 'vpc-example'] Project Description: [default: 'A simple getting started project for cdktf.']
Sau khi chạy
$ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
5, thư mục ví dụ chứa tài nguyên AWS của TypeScript để sử dụng.$ tree
├── .gen
│ └── providers
│ └── aws
│ ├── accessanalyzer-analyzer.ts
│ ├── # omitted for clarity
│ └── xray-sampling-rule.ts
│ └── modules
├── .terraform
├── cdktf.json
├── help
├── main.d.ts
├── main.js
├── main.ts
├── package.json
└── tsconfig.json
Trong
$ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
8, nhập đối tượng We will now setup the project. Please enter the details for your project.
If you want to exit, press ^C.
Project Name: [default: 'vpc-example']
Project Description: [default: 'A simple getting started project for cdktf.']
4 từ We will now setup the project. Please enter the details for your project.
If you want to exit, press ^C.
Project Name: [default: 'vpc-example']
Project Description: [default: 'A simple getting started project for cdktf.']
5. CDK cho Terraform tạo ra định nghĩa We will now setup the project. Please enter the details for your project.
If you want to exit, press ^C.
Project Name: [default: 'vpc-example']
Project Description: [default: 'A simple getting started project for cdktf.']
4 trong We will now setup the project. Please enter the details for your project.
If you want to exit, press ^C.
Project Name: [default: 'vpc-example']
Project Description: [default: 'A simple getting started project for cdktf.']
7. Tiếp theo, xác định VPC và khối CIDR của nó. Chúng tôi sử dụng Visual Studio Code tự động hoàn thành để điền vào định nghĩa tài nguyên.Để tạo một mạng con dựa trên định danh VPC, hãy chuyển
We will now setup the project. Please enter the details for your project.
If you want to exit, press ^C.
Project Name: [default: 'vpc-example']
Project Description: [default: 'A simple getting started project for cdktf.']
8 đến một đối tượng mạng con. $ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
8 cho thấy việc tạo ra VPC và mạng con dựa trên định danh của nó. Ví dụ sử dụng mã thông báo để chọn ID VPC làm loại chuỗi và cho phép CDK cho Terraform giải quyết giá trị của ID VPC sau đó trong tổng hợp.import { Construct } from 'constructs';
import { App, TerraformStack, Token } from 'cdktf';
import { Vpc } from './.gen/providers/aws/vpc';
import { Subnet } from './.gen/providers/aws/subnet';
import { AwsProvider } from './.gen/providers/aws'
class MyStack extends TerraformStack {
constructor[scope: Construct, name: string] {
super[scope, name];
new AwsProvider[this, 'aws', {
region: 'us-east-1'
}];
const vpc = new Vpc[this, 'my-vpc', {
cidrBlock: '10.0.0.0/16'
}];
new Subnet[this, 'my-subnet', {
vpcId: Token.asString[vpc.id],
cidrBlock: '10.0.0.0/24'
}];
}
}
const app = new App[];
new MyStack[app, 'vpc-example'];
app.synth[];
»Tổng hợp TypeScript với Cấu hình Terraform
Tiếp theo, tổng hợp TypeScript với cấu hình Terraform bằng cách chạy
$ tree
├── .gen
│ └── providers
│ └── aws
│ ├── accessanalyzer-analyzer.ts
│ ├── # omitted for clarity
│ └── xray-sampling-rule.ts
│ └── modules
├── .terraform
├── cdktf.json
├── help
├── main.d.ts
├── main.js
├── main.ts
├── package.json
└── tsconfig.json
0. Lệnh tạo các tệp cấu hình Terraform JSON trong thư mục $ tree
├── .gen
│ └── providers
│ └── aws
│ ├── accessanalyzer-analyzer.ts
│ ├── # omitted for clarity
│ └── xray-sampling-rule.ts
│ └── modules
├── .terraform
├── cdktf.json
├── help
├── main.d.ts
├── main.js
├── main.ts
├── package.json
└── tsconfig.json
1.$ cdktf synth
Generated Terraform code in the output directory: cdktf.out
$ tree cdktf.out
cdktf.out
├── .terraform
└── cdk.tf.json
Kiểm tra tệp Terraform JSON được tạo bằng cách kiểm tra
$ tree
├── .gen
│ └── providers
│ └── aws
│ ├── accessanalyzer-analyzer.ts
│ ├── # omitted for clarity
│ └── xray-sampling-rule.ts
│ └── modules
├── .terraform
├── cdktf.json
├── help
├── main.d.ts
├── main.js
├── main.ts
├── package.json
└── tsconfig.json
2. Nó bao gồm cấu hình Terraform cho VPC và nội suy ID VPC vào tài nguyên mạng con.{
"//": {
"metadata": {
"version": "0.0.10",
"stackName": "vpcexample"
}
},
"terraform": {
"required_providers": {
"aws": "~> 2.0"
}
},
"provider": {
"aws": [
{
"region": "us-east-1"
}
]
},
"resource": {
"aws_vpc": {
"vpcexample_myvpc_80A1790F": {
"cidr_block": "10.0.0.0/16",
"//": {
.....
}
}
},
"aws_subnet": {
"vpcexample_mysubnet_3769B309": {
"cidr_block": "10.0.0.0/24",
"vpc_id": "${aws_vpc.vpcexample_myvpc_80A1790F.id}",
"//": {
.....
}
}
}
}
}
Người dùng cũng có thể in cấu hình Terraform JSON trong thiết bị đầu cuối của họ bằng lệnh
$ tree
├── .gen
│ └── providers
│ └── aws
│ ├── accessanalyzer-analyzer.ts
│ ├── # omitted for clarity
│ └── xray-sampling-rule.ts
│ └── modules
├── .terraform
├── cdktf.json
├── help
├── main.d.ts
├── main.js
├── main.ts
├── package.json
└── tsconfig.json
3.Sau khi tổng hợp, người dùng có thể sử dụng quy trình khởi tạo, lập kế hoạch và áp dụng các thay đổi trong thư mục làm việc
$ tree
├── .gen
│ └── providers
│ └── aws
│ ├── accessanalyzer-analyzer.ts
│ ├── # omitted for clarity
│ └── xray-sampling-rule.ts
│ └── modules
├── .terraform
├── cdktf.json
├── help
├── main.d.ts
├── main.js
├── main.ts
├── package.json
└── tsconfig.json
1 hoặc sử dụng CDK cho Terraform CLI để chạy $ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
4.Quy trình làm việc của Terraform như sau:
$ cd cdktf.out
$ terraform init
$ terraform plan
Refreshing Terraform state in-memory prior to plan..
# omitted for clarity
$ terraform apply
# omitted for clarity
aws_vpc.vpcexamplemyvpc80A1790F: Creating...
aws_vpc.vpcexamplemyvpc80A1790F: Creation complete after 2s [id=vpc-09e8fffce46a61e3d]
aws_subnet.vpcexamplemysubnet3769B309: Creating...
aws_subnet.vpcexamplemysubnet3769B309: Creation complete after 0s [id=subnet-0b5b4c407444472e6]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
# destroy resources
$ terraform destroy
CDK cho Terraform CLI như sau:
$ cdktf deploy
Stack: vpcexample
Resources
+ AWS_SUBNET mysubnet aws_subnet.vpcexample_mysubnet_3769B309
+ AWS_VPC myvpc aws_vpc.vpcexample_myvpc_80A1790F
Diff: 2 to create, 0 to update, 0 to delete.
Do you want to continue [Y/n]?
Để phá hủy, từ thư mục gốc chạy
$ tree
├── .gen
│ └── providers
│ └── aws
│ ├── accessanalyzer-analyzer.ts
│ ├── # omitted for clarity
│ └── xray-sampling-rule.ts
│ └── modules
├── .terraform
├── cdktf.json
├── help
├── main.d.ts
├── main.js
├── main.ts
├── package.json
└── tsconfig.json
6.$ cdktf destroy
Ví dụ cho thấy sự tổng hợp của hai tài nguyên AWS. Để bao gồm các tài nguyên từ các nhà cung cấp khác, chẳng hạn như nhà cung cấp đầu bếp, thêm nhà cung cấp và phiên bản của nó vào
We will now setup the project. Please enter the details for your project.
If you want to exit, press ^C.
Project Name: [default: 'vpc-example']
Project Description: [default: 'A simple getting started project for cdktf.']
0.$ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
0Để tạo các đối tượng TypeScript cho nhà cung cấp Chef, hãy chạy
$ tree
├── .gen
│ └── providers
│ └── aws
│ ├── accessanalyzer-analyzer.ts
│ ├── # omitted for clarity
│ └── xray-sampling-rule.ts
│ └── modules
├── .terraform
├── cdktf.json
├── help
├── main.d.ts
├── main.js
├── main.ts
├── package.json
└── tsconfig.json
8.$ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
1Trong
$ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
8 Nhập import { Construct } from 'constructs';
import { App, TerraformStack, Token } from 'cdktf';
import { Vpc } from './.gen/providers/aws/vpc';
import { Subnet } from './.gen/providers/aws/subnet';
import { AwsProvider } from './.gen/providers/aws'
class MyStack extends TerraformStack {
constructor[scope: Construct, name: string] {
super[scope, name];
new AwsProvider[this, 'aws', {
region: 'us-east-1'
}];
const vpc = new Vpc[this, 'my-vpc', {
cidrBlock: '10.0.0.0/16'
}];
new Subnet[this, 'my-subnet', {
vpcId: Token.asString[vpc.id],
cidrBlock: '10.0.0.0/24'
}];
}
}
const app = new App[];
new MyStack[app, 'vpc-example'];
app.synth[];
0, import { Construct } from 'constructs';
import { App, TerraformStack, Token } from 'cdktf';
import { Vpc } from './.gen/providers/aws/vpc';
import { Subnet } from './.gen/providers/aws/subnet';
import { AwsProvider } from './.gen/providers/aws'
class MyStack extends TerraformStack {
constructor[scope: Construct, name: string] {
super[scope, name];
new AwsProvider[this, 'aws', {
region: 'us-east-1'
}];
const vpc = new Vpc[this, 'my-vpc', {
cidrBlock: '10.0.0.0/16'
}];
new Subnet[this, 'my-subnet', {
vpcId: Token.asString[vpc.id],
cidrBlock: '10.0.0.0/24'
}];
}
}
const app = new App[];
new MyStack[app, 'vpc-example'];
app.synth[];
1, import { Construct } from 'constructs';
import { App, TerraformStack, Token } from 'cdktf';
import { Vpc } from './.gen/providers/aws/vpc';
import { Subnet } from './.gen/providers/aws/subnet';
import { AwsProvider } from './.gen/providers/aws'
class MyStack extends TerraformStack {
constructor[scope: Construct, name: string] {
super[scope, name];
new AwsProvider[this, 'aws', {
region: 'us-east-1'
}];
const vpc = new Vpc[this, 'my-vpc', {
cidrBlock: '10.0.0.0/16'
}];
new Subnet[this, 'my-subnet', {
vpcId: Token.asString[vpc.id],
cidrBlock: '10.0.0.0/24'
}];
}
}
const app = new App[];
new MyStack[app, 'vpc-example'];
app.synth[];
2 đối tượng từ import { Construct } from 'constructs';
import { App, TerraformStack, Token } from 'cdktf';
import { Vpc } from './.gen/providers/aws/vpc';
import { Subnet } from './.gen/providers/aws/subnet';
import { AwsProvider } from './.gen/providers/aws'
class MyStack extends TerraformStack {
constructor[scope: Construct, name: string] {
super[scope, name];
new AwsProvider[this, 'aws', {
region: 'us-east-1'
}];
const vpc = new Vpc[this, 'my-vpc', {
cidrBlock: '10.0.0.0/16'
}];
new Subnet[this, 'my-subnet', {
vpcId: Token.asString[vpc.id],
cidrBlock: '10.0.0.0/24'
}];
}
}
const app = new App[];
new MyStack[app, 'vpc-example'];
app.synth[];
3. Tiếp theo xác định cấu hình sau.$ mkdir vpc-example
$ cd vpc-example
$ cdktf init --template=typescript
2Quy trình công việc tương tự áp dụng cho việc tổng hợp các tài nguyên cho các nhà cung cấp và mô -đun Terraform khác trong Cơ quan đăng ký Terraform. Nếu bạn muốn sử dụng Python để tạo cấu hình Terraform, hãy xem hướng dẫn bắt đầu cho Python.
»Hợp tác cộng đồng
Chúng tôi xin cảm ơn Sebastian Korfmann, người bảo trì dự án Terrastack, người đã giúp cung cấp CDK cho dự án Terraform. Nói chuyện với Sebastian, chúng tôi đã nhận ra rằng dự án Terrastack có tầm nhìn tương tự để cung cấp hỗ trợ cho ngôn ngữ lập trình bản địa cho tài nguyên Terraform. Chúng tôi rất vui mừng được chia sẻ rằng chúng tôi có Sebastian với tư cách là người duy trì dự án CDK cho Terraform và sẽ tiếp tục đóng góp cho dự án trong tương lai.
Ngoài ra, chúng tôi muốn nhận ra nhóm CDK AWS vì đã giúp chúng tôi khởi động dự án và cung cấp các đề xuất về các mẫu và thực tiễn cho các cấu trúc CDK và thư viện JSII.
"Cái gì tiếp theo
CDK cho Terraform là trong alpha và đang trong giai đoạn đầu phát triển. Dự án này là một cách khác để giao tiếp với Terraform bằng cách sử dụng các ngôn ngữ như TypeScript và Python. Chúng tôi đang làm việc để hỗ trợ các ngôn ngữ bổ sung như JavaScript, Java và C#. Ngoài hỗ trợ ngôn ngữ, chúng tôi có kế hoạch mở rộng phạm vi của CDK cho dự án Terraform để hỗ trợ các lệnh hạng nhất khác để cung cấp trải nghiệm người dùng tương tự như AWS CDK.
Tìm hiểu thêm về CDK cho Terraform tại Hashicorp/Terraform-CDK. Để biết thêm thông tin về AWS CDK và các khung của nó, hãy xem trang FAQ của nó. Các dự án hệ sinh thái bổ sung cho CDK bao gồm CDK cho Kubernetes.
Hãy tự mình thử nó với các ví dụ từng bước của chúng tôi bằng cách sử dụng hướng dẫn bắt đầu nhanh của Docker, AWS và các ví dụ khác trong Python và TypeScript.
Vì CDK cho Terraform là một dự án thử nghiệm, chúng tôi muốn yêu cầu cộng đồng phản hồi. Nếu bạn muốn xem một tính năng cho CDK cho Terraform, vui lòng xem lại các vấn đề và upvote hiện tại. Nếu một tính năng không tồn tại trong vấn đề GitHub, hãy thoải mái mở một vấn đề mới. Ngoài các vấn đề mở, bạn có thể đóng góp cho dự án bằng cách mở yêu cầu kéo. Ngoài ra, sử dụng biểu mẫu Hashicorp Thảo luận để đặt câu hỏi và chia sẻ phản hồi của bạn.