記事:
記事:
Import:
1GBあたりのストレージ料金は20%程度安い。
3,000IOPSまで無料かつ、ベースラインとして保証される。
スループットは125MB/秒まで無料かつ、ベースラインとして保証される。
root_block_device { volume_size = 10 volume_type = "gp3" iops = 3000 # 125MB/s throughput = 125 delete_on_termination = true }
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 3.74" } } }
provider "aws" { profile = "example" region = "ap-northeast-1" version = "< 4" }
terraform { required_version = ">= 0.12" required_providers { aws = { version = "~> 2.70" } } }
terraform { required_version = ">= 0.12" required_providers { aws = { version = "~> 3.0" } } }
locals { - domain_validation_options = var.dns_count > 0 ? aws_acm_certificate.example.domain_validation_options : {} + domain_validation_options = var.dns_count > 0 ? aws_acm_certificate.example.domain_validation_options : [] }
data "aws_vpc" "main" { filter { name = "tag:Name" values = ["example-dev-main"] } } data "aws_subnet_ids" "private" { vpc_id = data.aws_vpc.main.id tags = { Tier = "Private" } }
data "aws_instances" "web" { instance_tags = { "Name" = "web-*" } instance_state_names = ["running", "stopped"] } # 参照する場合 # count = length(data.aws_instances.web.ids) # data.aws_instances.web.public_ips[count.index]
// "${data.aws_region.main.name}" として参照できる data "aws_region" "main" {}
// "${data.aws_caller_identity.main.account_id}" として参照できる data "aws_caller_identity" "main" {}
locals { html_path = "./html/" } resource "aws_s3_bucket" "example" { bucket = "example-bucket" } resource "aws_s3_bucket_object" "example" { for_each = fileset(local.html_path, "**") bucket = aws_s3_bucket.example.bucket key = "${each.value}" source = "${local.html_path}${each.value}" etag = filemd5("${local.html_path}${each.value}") content_type = "text/html" }
terraform apply -target null_resource.backup_web_ebs1
resource "null_resource" "backup_web_ebs1" { count = length(aws_instance.web) provisioner "local-exec" { command = <<EOD aws ec2 create-tags \ --tags Key=backup:DailyBackup7Days,Value=${count.index == 0 ? true : false} \ --resources ${element(aws_instance.web[count.index].ebs_block_device[*].volume_id, 0)} \ --profile ${var.aws_profile} \ --region ${var.aws_region} EOD } }
locals { web_ebs1 = "${flatten(aws_instance.web.*.ebs_block_device)}" } resource "null_resource" "backup_web_ebs1" { count = "${length(aws_instance.web.*.id)}" provisioner "local-exec" { command = <<EOD aws ec2 create-tags \ --tags Key=backup:DailyBackup7Days,Value=${count.index == 0 ? true : false} \ --resources ${lookup(local.web_ebs1[count.index], "volume_id")} \ --profile ${var.aws_profile} \ --region ${var.aws_region} EOD } }
list[ list[ map{}, map{} ] ]
terraform refresh -target aws_instance.web
output "ebs_test01" { value = "${aws_instance.web[0].ebs_block_device}" } # 結果 ebs_test01 = [ { "delete_on_termination" = true "device_name" = "/dev/sdf" "encrypted" = false "iops" = 100 "kms_key_id" = "" "snapshot_id" = "" "volume_id" = "vol-0123456789abcdef" "volume_size" = 5 "volume_type" = "gp2" }, ] output "ebs_test02" { value = "${aws_instance.web[0].ebs_block_device[0].volume_id}" } # 結果: エラー # Block type "ebs_block_device" is represented by a set of objects, and set # elements do not have addressable keys. To find elements matching specific # criteria, use a "for" expression with an "if" clause. output "ebs_test03" { value = "${element(aws_instance.web[0].ebs_block_device[*].volume_id, 0)}" } # 結果 ebs_test03 = vol-0123456789abcdef
output "ebs_test01" { value = "${aws_instance.web.*.ebs_block_device}" } # result ebs_test01 = [ [ map[delete_on_termination:1 device_name:/dev/sdf encrypted:1 iops:100 snapshot_id: volume_id:vol-0123456789abcdef volume_size:5 volume_type:gp2] ], [ map[delete_on_termination:1 device_name:/dev/sdf encrypted:1 iops:100 snapshot_id: volume_id:vol-0f50829f1dfbc02ca volume_size:5 volume_type:gp2] ] ] output "ebs_test02" { value = "${lookup(aws_instance.web.0.ebs_block_device[0], "volume_id")}" } # result ebs_test02 = vol-0123456789abcdef output "ebs_test04" { value = "${slice(flatten(aws_instance.web.*.ebs_block_device[0]), 0, 1)}" } # result ebs_test04 = [ { delete_on_termination = 1, device_name = /dev/sdf, encrypted = 1, iops = 100, snapshot_id = , volume_id = vol-0123456789abcdef, volume_size = 5, volume_type = gp2 } ]
AWS上のIDが分かれているリソース(EC2, EBS, SecurityGroup)を作る場合、ID毎にリソースを分けて作成する事で保守性が上がる。
git clone https://github.com/builtinnya/aws-sns-slack-terraform.git cd aws-sns-slack-terraform/ pip install requests --upgrade export WEBHOOK_URL="hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX" export CHANNEL_MAP=`echo '{ "production-notices": "#webhook-tests" }' | base64` python sns-to-slack/lambda_function.py # jqでjsonを整形して見たい場合。 | grep "DEBUG EVENT:" | cut -c 14- | jq .
terraformのドキュメントの例には「policy = <json>」のように書いてある部分もあるが、毎回差分が出る不具合があるので、aws_iam_policy_documentを使うと良さそう。
resource "aws_s3_bucket_policy" "example" { bucket = "${aws_s3_bucket.example.id}" policy = "${data.aws_iam_policy_document.s3_example_public_read.json}" } data "aws_iam_policy_document" "s3_example_public_read" { statement { sid = "IPAllow" effect = "Allow" principals { type = "*" identifiers = ["*"] } actions = [ "s3:GetObject", ] resources = [ "arn:aws:s3:::example/*", ] condition { test = "IpAddress" variable = "aws:SourceIp" values = [ "192.0.2.0/24", # TEST-NET-1 "198.51.100.0/24",# TEST-NET-2 "203.0.113.0/24", # TEST-NET-3 ] } } }
記事:
aws ec2 associate-iam-instance-profile \ --instance-id i-123456 \ --iam-instance-profile "Name=example-role" \ --profile example }
cat ~/.aws/credentials [myprofile] aws_access_key_id = AK**** aws_secret_access_key = ****
aws configure --profile myprofile
variable "aws_profile" {} # awscli profile name. terraform plan/apply時にプロンプトを出す provider "aws" { profile = "${var.aws_profile}" region = "ap-northeast-1" # tokyo } provider "aws" { profile = "${var.aws_profile}" region = "us-east-1" alias = "us-east-1" } resource "aws_s3_bucket" "tokyo-example" { bucket = "tokyo.example.com" acl = "private" } resource "aws_s3_bucket" "us-east-1-example" { provider = "aws.us-east-1" bucket = "us-east-1.example.com" acl = "private" }
terraform import aws_s3_bucket.tokyo-example tokyo.example.com
terraform import -provider=aws.us-east-1 aws_s3_bucket.us-east-1-example virginia.example.com
variable "aws_region" { default = "ap-northeast-1" } // リクエスタ側のAWS account情報. aws configure --profile <name> で設定しておく variable "main_aws_profile" {} variable "main_aws_vpc_id" { default = "vpc-aaaaa" } variable "main_aws_route_table_id" { default = "rtb-11111111" } variable "main_aws_cidr" { default = "172.31.0.0/16" } provider "aws" { profile = "${var.main_aws_profile}" region = "${var.aws_region}" } // "${data.aws_caller_identity.main.account_id}" として参照可能 data "aws_caller_identity" "main" { } // アクセプタ側のAWS account情報 variable "peer_aws_account_id" { default = "2222222222" } variable "peer_vpc_id" { default = "vpc-bbbbb" } variable "peer_vpc_cidr" { default = "10.5.0.0/16" }
output "aws_iam_role.vpc_peering.arn" { value = "${aws_iam_role.vpc_peering.arn}" } resource "aws_iam_role" "vpc_peering" { name = "main-vpcpeering" assume_role_policy = "${data.aws_iam_policy_document.sts-assumerole.json}" } # AWS console上だとIAM > ロール > ロール名 > 信頼関係タブの部分 data "aws_iam_policy_document" "sts-assumerole" { statement { actions = [ "sts:AssumeRole", ] effect = "Allow" principals = { type = "AWS" identifiers = [ "arn:aws:iam::${var.peer_aws_account_id}:root", ] } } } # AWS console上だとIAM > ロール > ロール名 > アクセス許可タブ > インラインポリシーの部分 resource "aws_iam_role_policy" "vpc_peering" { name = "main-vpcpeering" role = "${aws_iam_role.vpc_peering.id}" policy = "${data.template_file.vpc_peering.rendered}" } data "template_file" "vpc_peering" { template = "${file("./policy/vpc-peering-connection.tpl")}" vars { aws_region = "${var.aws_region}" main_aws_account_id = "${data.aws_caller_identity.main.account_id}" main_aws_vpc_id = "${var.main_aws_vpc_id}" peer_aws_account_id = "${var.peer_aws_account_id}" peer_aws_vpc_id = "${var.peer_vpc_id}" } }
{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":"ec2:AcceptVpcPeeringConnection", "Resource":"arn:aws:ec2:${aws_region}:${main_aws_account_id}:vpc-peering-connection/*", "Condition":{ "ArnEquals":{ "ec2:RequesterVpc":"arn:aws:ec2:${aws_region}:${peer_aws_account_id}:vpc/${peer_aws_vpc_id}" } } }, { "Effect":"Allow", "Action":"ec2:AcceptVpcPeeringConnection", "Resource":"arn:aws:ec2:${aws_region}:${main_aws_account_id}:vpc/${main_aws_vpc_id}" } ] }
// Requester's side of the connection. // https://www.terraform.io/docs/providers/aws/r/vpc_peering.html resource "aws_vpc_peering_connection" "main" { vpc_id = "${var.main_aws_vpc_id}" peer_vpc_id = "${var.peer_vpc_id}" peer_owner_id = "${var.peer_aws_account_id}" auto_accept = false tags { Name = "VPC Peering between main and peer" Side = "Requester" } } resource "aws_route" "main" { route_table_id = "${var.main_aws_route_table_id}" destination_cidr_block = "${var.peer_vpc_cidr}" vpc_peering_connection_id = "${aws_vpc_peering_connection.main.id}" }
variable "peer_aws_route_table_id" { default = "rtb-22222" } // Accepter's credentials. provider "aws" { alias = "peer" profile = "peer" // aws configure --profile <name> で設定しておく region = "ap-northeast-1" } // Accepter's side of the connection. // https://www.terraform.io/docs/providers/aws/r/vpc_peering_accepter.html resource "aws_vpc_peering_connection_accepter" "peer" { provider = "aws.peer" vpc_peering_connection_id = "${aws_vpc_peering_connection.main.id}" auto_accept = true tags { Name = "VPC Peering between main and peer" Side = "Accepter" } } resource "aws_route" "peer" { provider = "aws.peer" route_table_id = "${var.peer_aws_route_table_id}" destination_cidr_block = "${var.main_aws_cidr}" vpc_peering_connection_id = "${aws_vpc_peering_connection_accepter.peer.id}" }
resource "aws_instance" "web01" { ... user_data = "${file("cloud-config.yaml")}" ... }
variable aws_subnets { type = "list" default = [ "subnet-aaaa", # AZ: ap-northeast-1a "subnet-cccc", # AZ: ap-northeast-1c ] } resource "aws_nat_gateway" "gw" { allocation_id = "${aws_eip.gw.*.id[count.index]}" subnet_id = "${var.aws_subnets[count.index]}" count = "${length(var.aws_subnets)}" } resource "aws_eip" "gw" { vpc = true count = "${length(var.aws_subnets)}" }
variable "ec2_subnets" { default = ["subnet-xxxx","subnet-xxxx","subnet-xxxx"] } resource "aws_instance" "web" { ... count = 4 subnet_id = "${var.ec2_subnets[count.index % length(var.ec2_subnets)]}" }
variable "cidr_common" { default = "192.168.2.1/32" } variable "cidr_example" { default = ["192.168.1.0/24", "10.5.1.0/24"] } resource "aws_security_group" "common" { ... cidr_blocks = [ "${var.cidr_common}", "${var.cidr_example}" ]
variable "instance_count_web" { default = 1 } # aws_elbは複数リソースがそのまま指定できる resource "aws_elb" "frontend" { instances = ["${aws_instance.web.*.id}"] } # aws_eipは一つのリソースしか指定できないので変換して渡す resource "aws_eip" "web" { count = "${var.instance_count_web}" instance = "${element(aws_instance.web.*.id, count.index)}" vpc = true }
"${element(aws_instance.web.*.id, 1)}"
AWS: aws_db_instance - Terraform by HashiCorp
classic network上にRDSを作る場合にsubnetのエラーが出る。v0.12.30 で確認
Error: Error creating DB Instance: InvalidVPCNetworkStateFault: Cannot create the DB Instance because db subnet group has not been specified which is required for a private DBInstance creation.
解決: