ãã®è¨äºã¯ãterraform Advent Calendar 2024 ã®7æ¥ç®ã®ã¨ã³ããªã§ãã
ã¯ããã«
terraformã§ãAWS S3ã¨TransferFamilyãçµã¿åããã¦ããã£ã¨sftpãµã¼ããä½ãã¾ãã
sftpã¦ã¼ã¶ãéµãã¡ã¤ã«ãä½µãã¦ä½ãã®ã§ãapplyå¾ã«sftpæ¥ç¶ã§ãã¾ãã
ãªããtfstateã«å
¬ééµãç§å¯éµãè¨è¼ããã¦ããããæ°ãä»ãã¦ãã ããã
ï¼Transfer Familyã触ã£ãã®ã¯åãã¦ã§ãããç¥ããªããµã¼ãã¹å¤ããï¼ï¼
AWS Transfer Familyã¨ã¯
å®å ¨ããã¼ã¸ããªãã¡ã¤ã«è»¢éãµã¼ãã¹ã§ãSFTPãFTPSãFTPã使ç¨ãã¦ãå®å ¨ã«ãã¼ã¿ãAWSã«ç§»åã§ãã¾ãã
åæ¥ç¶æ¹å¼ãæ¥ç¶å ãµã¼ãã¹(s3ãEFS)ãé¸æãããµã¼ããç¨æããããã«å¯¾ãã¦ãã¢ã¯ã»ã¹ããã¦ã¼ã¶ããã¼ã«ãæ¥ç¶å ï¼S3ãã±ããåãªã©ï¼ãæå®ãã¾ãã Transferã®ãµã¼ãã¼ã¯ããã¾ã§æ¥ç¶ã«é¢ããæ å ±ã®ã¾ã¨ã¾ãã§ãããä¾ãã°S3ãã±ããåãç´ã¥ããããã§ã¯ãªãã§ãããã®ããã1ã¤ã®ãµã¼ãã¼ã«å¯¾ããç°ãªããã¼ã«ãç°ãªãã¢ã¯ã»ã¹å ããã¤ã¦ã¼ã¶ãè¨å®ã§ãã¾ãã
åè Terraform Registry
ç°å¢
ç°å¢ã¨è¨å®
- terraform : v1.9.4
- ãã±ããå : advent-server
- sftpã¦ã¼ã¶å : sftp-advent
ãã¡ã¤ã«æ§æ
$ tree ./ ./ âââ main.tf âââ output.tf âââ terraform.tfvars âââ variables.tf
åãã¡ã¤ã«ã«ã¤ãã¦
terraform.tfvars
ãã±ããåãsftpã¦ã¼ã¶åãã¢ã¯ã»ã¹è¨é²ã®ããã®ãã°ã°ã«ã¼ãã®å¤æ°ãç¨æãã¾ãã
bucket_name = "advent-server" sftp_user = "sftp-advent" log_group = "/transfer/advent-server"
variables.tf
åå¤æ°ãå®ç¾©ãã¾ãã
variable "bucket_name" { type = string } variable "sftp_user" { type = string } variable "log_group" { type = string }
main.tf
ä½æãããªã½ã¼ã¹ã¨ãã¤ã³ããè¨è¼ãã¾ãã
- s3ãã±ãã
- force_destroy = true
- ãã±ããã空ã§ãªãã¦ãåé¤ãã¾ã
- force_destroy = true
- transferã«è¨å®ãããã¼ã«ã¨ããªã·ã¼
- ãã¼ã«ã«ããªã·ã¼ãã¢ã¿ãããã¾ã
- transferã«è¨å®ãããã°ã°ã«ã¼ã
- transferãµã¼ãã¼
- sftpæ¥ç¶ã§ä½æãã¾ã
- sftpã¦ã¼ã¶ã¨éµãã¡ã¤ã«
- ãã¼ã«ã«ã«ç§å¯éµãä¿åãã¾ã
provider "aws" { region = "ap-northeast-1" access_key = "AKIA**********" secret_key = "**************" } resource "aws_s3_bucket" "bucket" { bucket = var.bucket_name force_destroy = true # ãã±ããåé¤æã«ãªãã¸ã§ã¯ããåé¤ãã } resource "aws_iam_role" "transfer_role" { name = "TransferFamilyS3AccessRole" assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [ { "Sid" : "", "Effect" : "Allow", "Principal" : { "Service" : "transfer.amazonaws.com" }, "Action" : "sts:AssumeRole" } ] }) } resource "aws_iam_policy" "s3_access_policy" { name = "S3AccessPolicyForTransferFamily" policy = jsonencode({ Version = "2012-10-17", Statement = [ { "Sid" : "Statement1", "Effect" : "Allow", "Action" : [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource" : "${aws_s3_bucket.bucket.arn}" }, { "Sid" : "Statement2", "Effect" : "Allow", "Action" : [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject" ], "Resource" : "${aws_s3_bucket.bucket.arn}/*" } ] }) } resource "aws_iam_role_policy_attachment" "attach_s3_policy" { role = aws_iam_role.transfer_role.name policy_arn = aws_iam_policy.s3_access_policy.arn } resource "aws_cloudwatch_log_group" "transfer" { name_prefix = var.log_group } resource "aws_transfer_server" "sftp_server" { domain = "S3" protocols = ["SFTP"] # SFTPã¯éµèªè¨¼ã®ã¿ä½¿ãã¾ã identity_provider_type = "SERVICE_MANAGED" endpoint_type = "PUBLIC" # å¤é¨ããæ¥ç¶ã§ããããã«ãã structured_log_destinations = [ "${aws_cloudwatch_log_group.transfer.arn}:*" ] tags = { Name = "transfer-${var.bucket_name}" } } resource "aws_transfer_user" "sftp_user" { server_id = aws_transfer_server.sftp_server.id user_name = var.sftp_user role = aws_iam_role.transfer_role.arn home_directory = "/${var.bucket_name}" } resource "tls_private_key" "sftp_tls" { algorithm = "RSA" rsa_bits = 4096 } resource "aws_transfer_ssh_key" "sftp_ssh_key" { # SFTPæ¥ç¶ã¯éµèªè¨¼ã®ã¿ã server_id = aws_transfer_server.sftp_server.id user_name = aws_transfer_user.sftp_user.user_name body = trimspace(tls_private_key.sftp_tls.public_key_openssh) } resource "local_file" "private_key_file" { content = tls_private_key.sftp_tls.private_key_pem file_permission = "0600" filename = pathexpand("~/.ssh/${var.sftp_user}.pem") }
output.tf
æ¥ç¶ããããã®sftpã¨ã³ããã¤ã³ãã表示ãã¾ãã
output "sftp_endpoint" { value = aws_transfer_server.sftp_server.endpoint }
terraformã®å®è¡
terraform apply
transferã®ä½æã«3åã»ã©ãããã¾ããã
$ terraform apply Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_cloudwatch_log_group.transfer will be created + resource "aws_cloudwatch_log_group" "transfer" { ï¼ç¥ï¼ Plan: 10 to add, 0 to change, 0 to destroy. Changes to Outputs: + sftp_endpoint = (known after apply) Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes tls_private_key.sftp_tls: Creating... aws_cloudwatch_log_group.transfer: Creating... aws_iam_role.transfer_role: Creating... aws_s3_bucket.bucket: Creating... ï¼ç¥ï¼ Apply complete! Resources: 10 added, 0 changed, 0 destroyed. Outputs: sftp_endpoint = "******.server.transfer.ap-northeast-1.amazonaws.com" $
sftpæ¥ç¶
sftpæ¥ç¶ãããã¡ã¤ã«ã®ã¢ãããã¼ãããã¦ã³ãã¼ãã確èªã§ãã¾ããã
$ sftp -i ~/.ssh/sftp-advent.pem sftp-advent@******.server.transfer.ap-northeast-1.amazonaws.com Connected to ******.server.transfer.ap-northeast-1.amazonaws.com. sftp> pwd Remote working directory: /advent-server sftp> ls sftp> put main.tf Uploading main.tf to /advent-server/main.tf maintf 100% 2565 59.0KB/s 00:00 sftp> ls main.tf sftp> get main.tf Fetching /advent-server/main.tf to main.tf main.tf sftp> exit $
ãã®ä»
terraform destroyã§ããã±ããã«ãã¡ã¤ã«ãæ®ã£ã¦ãã¦ãå
¨ã¦åé¤ã§ãã¾ãããã¼ã«ã«ã®ç§å¯éµãåé¤ããã¾ãã
ã¾ããã«ã¹ã¿ã ãã¹ãåãä»ä¸ãããªãRoute53ã§ãã¹ãã¾ã¼ã³ã¨ã¬ã³ã¼ããä½æãã¾ãã
ããã¸ã¡ã³ãã³ã³ã½ã¼ã«ã§ã«ã¹ã¿ã ãã¹ãåãä»ãã¦Planããã¨ãããã¿ã°ã®ã¿ã®å·®ç°ã ã£ããããã¡ãã£ã¨ããã©ãããã£ã¦ã³ã¼ãã«ãã®ã¿ã°ãä»ããããã¹ãã¾ã¼ã³ã¨ã¬ã³ã¼ããä½æããã¾ããããã®å ´åãdestroyãã¦ããã¹ãã¾ã¼ã³ã¯æ®ã£ã¦ããã®ã§ããã®ããæ¹ã¯ãã¾ããããªããã ãããªã¨æãã¾ããã