記事:
記事:
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 myprofilevariable "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.
解決: