Khi bạn triển khai ứng dụng của mình lên EC2, bạn nên sử dụng các nhóm phân chia tỷ lệ. Các nhóm tự động thay đổi tỷ lệ cho phép ứng dụng của bạn mở rộng quy mô và đáp ứng nhu cầu hoặc khôi phục từ các phiên bản không thành công, tất cả đều không có bất kỳ sự can thiệp nào của con người. Tuy nhiên, để làm cho chúng hoạt động, hãy làm cho mọi phiên bản hoàn toàn sẵn sàng để phục vụ lưu lượng truy cập trực tiếp sau khi khởi động xong. Điều đó đòi hỏi nỗ lực nhiều hơn một chút so với việc chỉ triển khai ứng dụng của bạn tới một máy chủ, nếu bạn đã quen với việc thực hiện một số thay đổi trên máy chủ tin tức hoặc thực hiện triển khai ban đầu qua capistrano trước khi nó sẵn sàng hoạt động.
Ví dụ:chúng tôi có một ứng dụng web hướng tới người dùng được xây dựng bằng Rails. Khi khởi động xong, mỗi phiên bản cần phải có sẵn Rails đó và chờ phản hồi các yêu cầu được chuyển tiếp bởi bộ cân bằng tải. Để thực hiện điều này, trước tiên tôi đã tạo một tùy chỉnh AMI bằng cách chụp nhanh một phiên bản được cung cấp qua Ansible với ứng dụng, nginx, v.v. Sau đó, tôi đã định cấu hình nhóm tự động phân vùng với userdata thatinvokes một tập lệnh sao chép những gì capistrano làm cho việc triển khai - nó lấy mã mới nhất từ git, chạy Bundler, v.v. Vì vậy, với ứng dụng và tất cả các phụ thuộc của nó, những gì còn lại?
Bí mật ứng dụng:Bane của người triển khai
Bí mật ứng dụng đưa ra một thách thức:bạn muốn giữ chúng không được lưu trữ ở nơi chúng có thể bị lộ ra (chẳng hạn như trong git repo của bạn), nhưng bạn cần chúng có sẵn cho ứng dụng của mình khi ứng dụng đang chạy. Và tính năng tự động tính toán song song, bạn không thể dựa vào một con người ở đó để đưa chúng vào vị trí cho ứng dụng của bạn khi ứng dụng cần.
Một câu trả lời cho vấn đề này là Vault của Hashicorp. Đó là một phần mềm tuyệt vời được viết riêng để giải quyết vấn đề này, đồng thời giữ bí mật của bạn cho đến khi ứng dụng của bạn cần chúng. Tuy nhiên, nhược điểm là bạn phải cung cấp và quản lý Vault - đó là một dịch vụ khác mà bạn cần tiếp tục chạy.
Một tùy chọn khác là lưu các bí mật trong bộ nhớ dùng chung (đương nhiên là S3) và đảm bảo rằng chỉ các phiên bản của bạn mới có quyền truy cập vào nhóm và / orkey đó. Điều này có thể được thực hiện bằng cách sử dụng các vai trò IAM, có thể có các chính sách được gắn vào chúng để cấp quyền truy cập vào các tài nguyên S3 bị hạn chế. Tuy nhiên, Thatstill khiến bạn có thể tiếp xúc không mong muốn, nếu bạn lưu trữ tất cả các bí mật trong văn bản rõ ràng trên S3. Có thể vô tình dữ liệu makethat có sẵn cho những người khác có quyền truy cập vào thùng đó hoặc thậm chí là thế giới lỗ hổng.
Sẽ thật tuyệt nếu bạn có thể mã hóa bí mật của mình trước khi lưu chúng trên S3, sau đó tải và giải mã chúng trong ứng dụng khi bạn cần?
Thành phần bí mật:Dịch vụ quản lý chính của Amazon
Dịch vụ quản lý khóa của Amazon (KMS) cung cấp một API forinteractive với các khóa mã hóa. Khi được kết hợp với các vai trò IAM và mô-đun mã hóa theAws ::S3 ::, chỉ mất một vài dòng mã để tải các bí mật của bạn vào ứng dụng của bạn trong khi vẫn mã hóa chúng trênS3.
Trước khi tìm hiểu kỹ, tôi phải cảm ơn Don Mills, người đã viết một bài đăng tuyệt vời bằng cách sử dụng KMS plus S3 để lưu trữ bí mật. Tôi đã thay đổi khoảng cách của anh ấy một chút bằng cách tùy thuộc vào các vai trò IAM và theo dõi khóa KMS một cách riêng biệt thay vì lưu trữ thông tin khóa cùng với các bí mật trênS3.
KMS tạo và cung cấp quyền truy cập vào khóa mã hóa chính mà bạn có thể sử dụng để mã hóa và giải mã dữ liệu. Khi bạn yêu cầu nó mã hóa thứ gì đó, KMS sẽ giao cho bạn một khóa tạm thời dựa trên khóa chính và khóa tạm thời đó có thể được sử dụng để mã hóa hoặc giải mã.
Để tạo khóa, bạn đi tới bảng điều khiển IAM và chọn liên kết Khóa mã hóa. Khi bạn tạo khóa, bạn sẽ được yêu cầu chỉ định người dùng IAM hoặc vai trò sẽ có khả năng sử dụng khóa này. Chọn vai trò sẽ được chỉ định cho các phiên bản EC2 sẽ là một phần của nhóm tự động phân tỷ lệ. Lưu ý ARN của khóa - bạn sẽ sử dụng khóa đó.
Tạo Roux:Các bộ phận bằng nhau KMS và IAM
Khi bạn đã tạo khóa, hãy sử dụng bảng điều khiển IAM để chỉnh sửa vai trò IAM mà bạn đã chọn. Cấp quyền truy cập vào nhóm nơi bí mật sẽ được lưu trữ bằng cách gắn một chính sách như sau:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1476277816000",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:HeadObject"
],
"Resource": [
"arn:aws:s3:::yourbucket/secrets.yml"
]
}
]
}
Với khóa được định cấu hình và chính sách được đính kèm với vai trò, bạn có thể tương tác với KMS và S3 thông qua phiên bản Aws ::S3 ::Encryption ::Client. Dưới đây là một số mã mẫu để truy xuất tệp bí mật và tải nội dung của nó vào các biến môi trường:
begin
es3 = Aws::S3::Encryption::Client.new(kms_key_id: ENV['KMS_KEY_ID'])
YAML.load(es3.get_object(bucket: "yourbucket", key: "secrets.yml").body.read).each do |k, v|
ENV[k] ||= v # Don't override local ENV settings
end
rescue ArgumentError
# Raised when no KMS_KEY_ID was found in ENV, so there's nothing to do
rescue Aws::S3::Errors::NoSuchKey
# No secrets file was found, so there's nothing to do
end
Đầu tiên, chúng tôi khởi tạo một đối tượng mới với ID của khóa KMS. ARN cho khóa (được hiển thị trong bảng điều khiển IAM khi bạn tạo khóa) được lưu trữ trong biến môi trường KMS_KEY_ID. Khi bạn chuyển keyID cho hàm tạo ở đây, nó sẽ xử lý việc tìm nạp các khóa mã hóa tạm thời cho bạn. Bạn có thể chỉ định phiên bản Aws ::S3 ::Client như một tùy chọn ở đây, nếu bạn muốn sử dụng một tập hợp thông tin xác thực riêng biệt cho S3 mà bạn đang sử dụng để nói chuyện với KMS. Tuy nhiên, nếu bạn đã thiết lập vai trò IAM trước đó, bạn không cần phải làm như vậy, vì Aws ::S3 ::Encryption ::Máy khách sẽ tạo một phiên bản Aws ::S3 ::Máy khách mới cho bạn với thông tin xác thực được cung cấp bởi vai trò IAM.
Với ứng dụng khách S3 đã mã hóa sẵn sàng, hãy sử dụng #get_object để tìm nạp dữ liệu từ S3 và giải mã nó bằng khóa do KMS cung cấp. Khi bạn có dữ liệu, bạn có thể làm những gì bạn muốn với nó. Dữ liệu của chúng tôi là YAML, vì vậy chúng tôi tải và nhồi các cặp khóa / giá trị vào ENV để sử dụng mã ứng dụng.
Thả mã này vào tệp trình khởi tạo trong ứng dụng Rails của bạn và bạn đã sẵn sàng. Vâng, một khi bạn đã lưu trữ bí mật của mình trên S3, thatis. :) Giả sử bạn có bảng điều khiển IRB trên một phiên bản đang chạy với vai trò IAM phù hợp, bạn có thể làm điều gì đó như sau để lưu trữ bí mật của mình:
# Encrypt the data from /path/to/secrets.yml and store it on S3
Aws::S3::Encryption::Client.new(kms_key_id: ENV['KMS_KEY_ID']).
put_object(bucket: "yourbucket", key: "secrets.yml", body: File.read("/path/to/secrets.yml"))
Phục vụ ngay lập tức
Giờ đây, bạn luôn có sẵn các bí mật cho bất kỳ phiên bản mới nào được thêm vào nhóm tự động phân vùng của bạn trong khi vẫn giữ bí mật được mã hóa. Mọi người đều thắng! :)