TerraformでAWSを使う(Terraform学習備忘録 #3)
Terraformを学習内容を備忘録として残します。versionはv1.6です。
VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
enable_dns_support = "true"
enable_dns_hostnames = "true"
tags = {
Name = "main"
}
}
cidr_block
– (オプション)VPCのIPv4 CIDRブロック。CIDRは明示的に設定するか、IPv4_netmask_lengthを使用してIPAMから導き出すことができます。instance_tenancy
– (オプション) VPCに起動されるインスタンスのテナンシーオプション。デフォルトはdefault。他の唯一のオプションはdedicatedです。default
– デフォルトの設定で、複数のAWSアカウントが同じ物理ハードウェアを共有します。これは、インスタンスがホスト上で共有されることを意味します。dedicated
– インスタンスはシングルテナントのハードウェアで実行されます。これは、単一のカスタマー専用のハードウェアのVirtual Private Cloud (VPC)で実行されるAmazon EC2インスタンスを意味します。リージョンごとの専用使用料が1時間あたり2ドル、さらにインスタンスごとの使用料が1時間あたり1ドルかかります。
enable_dns_support
– (オプション) VPC が Amazon 提供の DNS サーバーを介した DNS 解決策をサポートするかどうかを決定します。デフォルトはtrueです。- (補足) VPCのDNS(Amazon Route 53 Resolver)は、VPC内のリソース(例えば、EC2インスタンスやRDSデータベースなど)間の名前解決を行うために使用されます。VPC内の異なるアベイラビリティゾーンにあるサーバ間の通信においても、VPCのDNSは役立ちます。例えば、あるEC2インスタンスが別のEC2インスタンスに接続するためには、そのインスタンスのIPアドレスまたはホスト名が必要です。VPCのDNSは、インスタンスのプライベートDNSホスト名を解決し、対応するプライベートIPアドレスを返すことで、この名前解決を行います。
enable_dns_hostnames
– (オプション) VPC がパブリック IP アドレスを持つインスタンスへのパブリック DNS ホスト名の割り当てをサポートするかどうかを決定します。デフォルトはfalseです。tags
– (オプション)リソースに割り当てるタグのマップ。プロバイダのdefault_tags
設定ブロックが存在する状態で設定された場合、一致するキーを持つタグはプロバイダ・レベルで定義されたものを上書きします。
Subnet
resource "aws_subnet" "main-public-1" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = "true"
availability_zone = "ap-northeast-1a"
tags = {
Name = "main-public-1"
}
}
vpc_id
– (必須) VPC ID。cidr_block
– (オプション)サブネットのIPv4 CIDRブロック。map_public_ip_on_launch
– (オプション)サブネットに起動したインスタンスにパブリックIPアドレスを割り当てる必要がある場合はtrue
を指定します。デフォルトはfalse
です。availability_zone
– (オプション)サブネットの AZ。tags
– (オプション)リソースに割り当てるタグのマップ。プロバイダのdefault_tags
設定ブロックが存在する状態で設定された場合、一致するキーを持つタグはプロバイダ・レベルで定義されたものを上書きします。
Internet Gateway
resource "aws_internet_gateway" "main-gw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main"
}
}
vpc_id
– (オプション)作成する VPC ID。tags
– (オプション)リソースに割り当てるタグのマップ。プロバイダのdefault_tags
設定ブロックが存在する状態で設定された場合、一致するキーを持つタグはプロバイダ・レベルで定義されたものを上書きします。
Route Table
resource "aws_route_table" "main-public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main-gw.id
}
tags = {
Name = "main-public-1"
}
}
vpc_id
– (必須) VPC ID。route
– (オプション)ルートテーブルに追加するルートオブジェクトのリストを指定するためのもの。各ルートオブジェクトは、特定の送信先(CIDRブロック)から特定のターゲット(例えば、インターネットゲートウェイやNATゲートウェイなど)への経路を定義します。route
はattribute-as-blocks
(属性としてのブロック)モードで処理されます。このroute
という引数を省略すると、すでに設定されているルートテーブルには何ら影響を与えません。管理されているすべてのルートを削除するには、空のリストを指定する必要があります。tags
– (オプション)リソースに割り当てるタグのマップ。プロバイダのdefault_tags
設定ブロックが存在する状態で設定された場合、一致するキーを持つタグはプロバイダ・レベルで定義されたものを上書きします。
Route Table Association
ルートテーブルとサブネット、またはルートテーブルとインターネットゲートウェイやバーチャルプライベートゲートウェイとの関連付けを作成するためのリソースを提供します。
resource "aws_route_table_association" "main-public-1-a" {
subnet_id = aws_subnet.main-public-1.id
route_table_id = aws_route_table.main-public.id
}
subnet_id
– (オプション) 関連付けを作成するサブネットID。gateway_id
と競合します。subnet_id
とgateway_id
のどちらかは必ず必要です。route_table_id
– (必須)関連付けるルーティング・テーブルの ID。
Nat Gateway
resource "aws_eip" "nat" {
domain = "vpc"
}
resource "aws_nat_gateway" "nat-gw" {
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.main-public-1.id
depends_on = [aws_internet_gateway.main-gw]
}
aws_eip
リソースは、AWSの Elastic IPアドレス(EIP) を確保するために使用されます。EIPは、AWSのパブリックIPv4アドレスで、AWSアカウントに関連付けられています。EIPは、AWSリソース(例えば、EC2インスタンスやNATゲートウェイなど)に関連付けることができます。
一方、aws_nat_gateway
リソースは、AWSのNATゲートウェイを作成するために使用されます。NATゲートウェイは、プライベートサブネット内のインスタンスがインターネットや他のAWSサービスに接続できるようにするためのゲートウェイです。
NATゲートウェイを作成する際には、EIP( aws_eip
リソースで確保したもの)を指定する必要があります。これは、NATゲートウェイはデフォルトでパブリックIPアドレスが付与されないため、インターネットに接続するためにパブリックIPアドレス(つまり、EIP)が必要になるためです。
domain
– このEIPがVPC(vpc)で使用されるかどうかを示す。allocation_id
– (オプション) NATゲートウェイのElastic IPアドレスの割り当てID。connectivity_type
がpublic
の場合は必須。subnet_id
– (必須) NAT ゲートウェイを配置するサブネットのサブネット ID。depends_on
– インターネット・ゲートウェイへの明示的な依存関係は、NATゲートウェイがインターネット・ゲートウェイの後に作成されることを保証し、リソース・プロビジョニングの正しい順序を維持します。
Security Group
ingress
(インバウンドの制御) と egress
(アウトバウンドの制御) のルールをインラインで定義したSecurity Group
のリソースと、1つ以上の ingress
または egress
のルールを管理する Security Group Rule
リソースが提供されています。これらのリソースはどちらもAWSがセキュリティグループルールの一意なIDを割り当てる前に追加されたもので、一意なIDに依存する description
属性や tags
属性を使ったすべてのシナリオでうまく動作しません。つまり、どちらも設定している場合、期待通りに動かない可能性があります。
aws_vpc_security_group_egress_rule
と aws_vpc_security_group_ingress_rule
リソースは、これらの制限に対処するために追加されたもので、すべての新しいセキュリティグループルールに使用する必要があります。 aws_vpc_security_group_egress_rule
とaws_vpc_security_group_ingress_rule
リソースは、インラインルールの aws_security_group
リソースや、同じ Security Group
に定義された aws_security_group_rule
リソースと組み合わせて使用してはいけません。ルールの競合が発生し、ルールが上書きされる可能性があります。
resource "aws_security_group" "allow-ssh" {
vpc_id = aws_vpc.main.id
name = "allow-ssh"
description = "security group that allows ssh and all egress traffic"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "allow-ssh"
}
}
- vpc_id – (オプション、強制新規リソース) VPC ID。デフォルトはリージョンのデフォルト VPC です。
egress
– (オプション、VPC のみ)egress
ルールの構成ブロック。egress
ルールごとに複数回指定できます。各egress
ブロックは、以下で説明するフィールドをサポートします。この引数は、attribute-as-blocks
モードで処理されます。ingress
– (オプション) イングレス・ルールの構成ブロック。イングレス・ルールごとに複数回指定できる。各ingress
ブロックは、以下に文書化されたフィールドをサポートする。この引数はattribute-as-blocks
モードで処理される。tags
– (オプション)リソースに割り当てるタグのマップ。プロバイダのdefault_tags
設定ブロックが存在する状態で設定された場合、一致するキーを持つタグはプロバイダレベルで定義されたものを上書きします。
EC2
resource "aws_instance" "example" {
ami = var.AMIS[var.AWS_REGION]
instance_type = "t2.micro"
# the VPC subnet
subnet_id = aws_subnet.main-public-1.id
# the security group
vpc_security_group_ids = [aws_security_group.allow-ssh.id]
# the public SSH key
key_name = aws_key_pair.mykeypair.key_name
}
ami
-(オプション)インスタンスに使用するAMI。launch_template
が指定され、Launch Template で AMI が指定されていない場合は必須。Launch TemplateでAMIが指定されている場合、ami
を設定するとLaunch Templateで指定されているAMIが上書きされます。instance_type
– (オプション)インスタンスに使用するインスタンス・タイプ。launch_template
が指定され、Launch Template がインスタンス・タイプを指定しない限り、必須です。Launch Templateでインスタンスタイプが指定されている場合、instance_type
を設定するとLaunch Templateで指定されているインスタンスタイプが上書きされます。このフィールドを更新すると、EC2インスタンスの停止/起動がトリガーされる。subnet_id
– (オプション)起動するVPCサブネットID。vpc_security_group_ids
– (オプション、VPCのみ)関連付けるセキュリティ・グループIDのリスト。key_name
– (オプション)aws_key_pair
のリソースを使用して管理できます。
Key Pair
キー・ペアは、EC2インスタンスへのログイン・アクセスを制御するために使用されます。ユーザーが提供する既存のキーペアが必要です。この鍵ペアの公開鍵がAWSに登録され、EC2インスタンスへのログインが可能になります。既存の鍵ペアをインポートする場合、公開鍵の素材はAWSがサポートするフォーマットであれば何でもよいです。
resource "aws_key_pair" "mykeypair" {
key_name = "mykeypair"
public_key = file(var.PATH_TO_PUBLIC_KEY)
}
key_name
– (オプション) キーペアの名前。key_name
もkey_name_prefix
も指定しない場合、Terraformは接頭辞terraform-
を使って一意なキー名を作成します。public_key
– (必須) 公開鍵の素材。
EBS
resource "aws_ebs_volume" "ebs-volume-1" {
availability_zone = "ap-northeast-1a"
size = 20
type = "gp2"
tags = {
Name = "extra volume data"
}
}
availability_zone
– (必須)EBSボリュームが存在するAZ。size
– (オプション)ドライブのサイズ(GiB単位)。type
– (オプション)EBSボリュームのタイプ。standard、gp2、gp3、io1、io2、sc1、またはst1を指定できます(デフォルト:gp2)。tags
– (オプション)リソースに割り当てるタグのマップ。プロバイダのdefault_tags
設定ブロックが存在する状態で設定された場合、一致するキーを持つタグはプロバイダ・レベルで定義されたものを上書きします。
Volume Attachment
resource "aws_volume_attachment" "ebs-volume-1-attachment" {
device_name = "/dev/xvdh"
volume_id = aws_ebs_volume.ebs-volume-1.id
instance_id = aws_instance.example.id
stop_instance_before_detaching = true
}
device_name
– (必須)インスタンスに公開するデバイス名(例:/dev/sdh
またはxvdh
)。volume_id
– (必須)アタッチするボリュームのID。instance_id
– (必須)アタッチするインスタンスの ID。stop_instance_before_detaching
– (オプション、ブール値) これをtrue
に設定すると、ボリュームのデタッチを試みる前にターゲット・インスタンスが確実に停止します。インスタンスがまだ停止していない場合、インスタンスを停止します。
User Data, Cloud Init
resource "aws_instance" "example" {
ami = var.AMIS[var.AWS_REGION]
instance_type = "t2.micro"
# the VPC subnet
subnet_id = aws_subnet.main-public-1.id
# the security group
vpc_security_group_ids = [aws_security_group.allow-ssh.id]
# the public SSH key
key_name = aws_key_pair.mykeypair.key_name
# user data
user_data = data.cloudinit_config.cloudinit-example.rendered
}
user_data
(オプション)- インスタンスの起動時に提供するユーザーデータです。この引数を通じてgzip
圧縮されたデータを渡すことはできません。その代わりにuser_data_base64
を参照してください。このフィールドへの更新は、デフォルトではEC2インスタンスの停止/開始をトリガーします。user_data_replace_on_change
が設定されている場合、このフィールドへの更新はインスタンスの破棄と再作成をトリガーします。
cloudinit_config
は、クラウドコンピューティングインスタンスの起動時に実行する設定スクリプトを提供するために使用されます。インスタンスが起動すると同時に必要な設定やインストールが行われるため、手動での作業を省略できます。
## cloudinit.tf
# note: previous templatefile datasources have been replaced by the template_file() function
data "cloudinit_config" "cloudinit-example" {
gzip = false
base64_encode = false
part {
filename = "init.cfg"
content_type = "text/cloud-config"
content = templatefile("scripts/init.cfg", {
REGION = var.AWS_REGION
})
}
part {
content_type = "text/x-shellscript"
content = templatefile("scripts/volumes.sh", {
DEVICE = var.INSTANCE_DEVICE_NAME
})
}
}
part
(ブロックリスト)- (必須)生成 さ れ るcloud-init
設定に フ ァ イ ルを追加する入れ子ブロック 型。複数のパートブロックを使って複数のファイルを指定し、最終的な MIME ドキュメントに宣言順に含まれるようにします。content
(文字列)- (必須)part
の本文。content_type
(文字列)- (オプション) その部分のヘッダで報告したい MIME 形式のコンテントタイプ。デフォルトはtext/plain
filename
(文字列)- (オプション)部分のヘッダで報告したいファイル名。
## init.cfg
#cloud-config
repo_update: true
repo_upgrade: all
packages:
- lvm2
output:
all: '| tee -a /var/log/cloud-init-output.log'
## volumes.sh
#!/bin/bash
set -ex
vgchange -ay
DEVICE_FS=`blkid -o value -s TYPE ${DEVICE} || echo ""`
if [ "`echo -n $DEVICE_FS`" == "" ] ; then
# wait for the device to be attached
DEVICENAME=`echo "${DEVICE}" | awk -F '/' '{print $3}'`
DEVICEEXISTS=''
while [[ -z $DEVICEEXISTS ]]; do
echo "checking $DEVICENAME"
DEVICEEXISTS=`lsblk |grep "$DEVICENAME" |wc -l`
if [[ $DEVICEEXISTS != "1" ]]; then
sleep 15
fi
done
# make sure the device file in /dev/ exists
count=0
until [[ -e ${DEVICE} || "$count" == "60" ]]; do
sleep 5
count=$(expr $count + 1)
done
pvcreate ${DEVICE}
vgcreate data ${DEVICE}
lvcreate --name volume1 -l 100%FREE data
mkfs.ext4 /dev/data/volume1
fi
mkdir -p /data
echo '/dev/data/volume1 /data ext4 defaults 0 0' >> /etc/fstab
mount /data
# install docker
curl https://get.docker.com | bash
Elastic IP, Route53
## route53.tf
resource "aws_route53_zone" "newtech-academy" {
name = "newtech.academy"
}
resource "aws_route53_record" "server1-record" {
zone_id = aws_route53_zone.newtech-academy.zone_id
name = "server1.newtech.academy"
type = "A"
ttl = "300"
records = ["104.236.247.8"]
}
resource "aws_route53_record" "www-record" {
zone_id = aws_route53_zone.newtech-academy.zone_id
name = "www.newtech.academy"
type = "A"
ttl = "300"
records = ["104.236.247.8"]
}
resource "aws_route53_record" "mail1-record" {
zone_id = aws_route53_zone.newtech-academy.zone_id
name = "newtech.academy"
type = "MX"
ttl = "300"
records = [
"1 aspmx.l.google.com.",
"5 alt1.aspmx.l.google.com.",
"5 alt2.aspmx.l.google.com.",
"10 aspmx2.googlemail.com.",
"10 aspmx3.googlemail.com.",
]
}
output "ns-servers" {
value = aws_route53_zone.newtech-academy.name_servers
}
aws_route53_zone
Route53 Hosted Zoneを管理します。
name
– (必須) ホストされているゾーンの名前です。
aws_route53_record
Route53 レコードリソースを提供します。
zone_id
– (必須) このレコードを含むホストされているゾーンの ID。name
– (必須)レコードの名前。type
– (必須) レコードタイプ。有効な値は、A、AAAA、CAA、CNAME、DS、MX、NAPTR、NS、PTR、SOA、SPF、SRV、TXTです。ttl
– (非エイリアスレコードでは必須)レコードのTTL。records
– (非エイリアスレコードの場合は必須) レコードの文字列リスト。DKIM用のTXTレコードなど、255文字より長いレコード値を1つだけ指定する場合は、Terraformの設定文字列の中に\"\"
を追加します(例:"first255characters\"\"morecharacters"
)。
RDS
resource "aws_db_subnet_group" "mariadb-subnet" {
name = "mariadb-subnet"
description = "RDS subnet group"
subnet_ids = [aws_subnet.main-private-1.id, aws_subnet.main-private-2.id]
}
resource "aws_db_parameter_group" "mariadb-parameters" {
name = "mariadb-parameters"
family = "mariadb10.4"
description = "MariaDB parameter group"
parameter {
name = "max_allowed_packet"
value = "16777216"
}
}
resource "aws_db_instance" "mariadb" {
allocated_storage = 100 # 100 GB of storage, gives us more IOPS than a lower number
engine = "mariadb"
engine_version = "10.4"
instance_class = "db.t2.small" # use micro if you want to use the free tier
identifier = "mariadb"
db_name = "mariadb"
username = "root" # username
password = var.RDS_PASSWORD # password
db_subnet_group_name = aws_db_subnet_group.mariadb-subnet.name
parameter_group_name = aws_db_parameter_group.mariadb-parameters.name
multi_az = "false" # set to true to have high availability: 2 instances synchronized with each other
vpc_security_group_ids = [aws_security_group.allow-mariadb.id]
storage_type = "gp2"
backup_retention_period = 30 # how long you’re going to keep your backups
availability_zone = aws_subnet.main-private-1.availability_zone # prefered AZ
skip_final_snapshot = true # skip final snapshot when doing terraform destroy
tags = {
Name = "mariadb-instance"
}
}
aws_db_subnet_group
name
– (オプション、強制新規リソース) DBサブネットグループの名前。省略した場合、Terraform はランダムでユニークな名前を割り当てます。description
– (オプション) DB サブネットグループの説明。デフォルトは “Managed by Terraform”。subnet_ids
– (必須) VPCサブネットIDのリスト。
aws_db_parameter_group
name
– (オプション、強制新規リソース) DBパラメータグループの名前。省略した場合、Terraformはランダムでユニークな名前を割り当てます。family
– (必須、強制新規リソース) DB パラメータグループのファミリ。description
– (オプション、強制新規リソース) DB パラメータグループの説明。デフォルトは “Managed by Terraform” です。
aws_db_instance
allocated_storage
-(snapshot_identifier
またはreplicate_source_db
が指定さ れていない場合は必須)割り当て済みストレージ。max_allocated_storage
が設定されている場合、この引数は最初のストレージ割り当てを表し、Storage Autoscaling
が発生すると設定との違いは自動的に無視されます。replicate_source_db
が設定されている場合、この値はインスタンスの作成時には無視されます。engine
– (snapshot_identifier
またはreplicate_source_db
が指定されていない場合は必須) 使用するデータベース・エンジン。Amazon Auroraインスタンスの場合、エンジンはDBクラスタのエンジンと一致しなければならないことに注意してください。engine_version
– (オプション) 使用するエン ジ ンのバージ ョ ン。auto_minor_version_upgrade
が有効になっている場合は、5.7
(5.7.10
の場合) のようにバージョンのプレフィックスを指定することができます。実際に使用す る エン ジ ンバージ ョ ンは属性engine_version_actual
で返されます。Amazon Auroraインスタンスの場合、エンジンバージョンはDBクラスタのエンジンバージョンと一致しなければならないことに注意してください。instance_class
– (必須) RDSインスタンスのインスタンスタイプ。identifier
– (オプション) RDSインスタンスの名前。省略した場合、Terraformはランダムな一意の識別子を割り当てます。restore_to_point_in_time
が指定されている場合は必須。db_name
– (オプション) DB インスタンスの作成時に作成するデータベースの名前。このパラメータを指定しない場合、DB インスタンスにデータベースは作成されません。Oracle や SQL Server エンジンには適用されないことに注意してください。Oracle DB 名を指定する場合は、すべて大文字にする必要があります。レプリカには指定できません。username
– (snapshot_identifier
またはreplicate_source_db
が指定されていない場合は必須) マスターDBユーザのユーザ名。レプリカには指定できません。password
– (manage_master_user_password
がtrue
に設定されている場合、またはsnapshot_identifier
またはreplicate_source_db
が指定されている場合、またはmanage_master_user_password
が設定されている場合を除き、必須)マスターDBユーザのパスワード。これはログに表示される可能性があり、状態ファイルに保存されることに注意してください。manage_master_user_password
がtrue
に設定されている場合は設定できません。db_subnet_group_name
– (オプション) DB サブネットグループの名前。DBインスタンスはDBサブネットグループに関連付けられたVPCに作成される。未指定の場合、デフォルトのVPC、またはEC2クラシック(利用可能な場合)に作成される。リードレプリカを使用する場合は、ソースデータベースが別のAWSリージョンにあるインスタンスを指定している場合のみ指定する。parameter_group_name
– (オプション) 関連付ける DB パラメータ・グループの名前。multi_az
– (オプション) RDSインスタンスがマルチAZであるかどうかを指定します。vpc_security_group_ids
– (オプション)関連付けるVPCセキュリティグループのリスト。storage_type
– (オプション) “standard”(磁気)、”gp2″(汎用SSD)、”gp3″(iopsが独立して必要な汎用SSD)、”io1″(プロビジョニングされたIOPS SSD)のいずれか。デフォルトは、iops
が指定されている場合は “io1″、指定されていない場合は “gp2″です。backup_retention_period
– (オプション)バックアップを保持する日数。0
から35
の間で設定する必要があります。デフォルトは0
です。データベースがRead Replica
のソースとして使用される場合、低ダウンタイム更新を使用する場合、またはRDS Blue/Green
デプロイメントを使用する場合は、0より大きくする必要があります。availability_zone
– (オプション)RDSインスタンスのAZ。skip_final_snapshot
– (オプション) DB インスタンスが削除される前に DB の最終スナップショットを作成するかどうかを決定します。true
を指定すると、DBSnapshot は作成されません。false
を指定すると、DB インスタンスが削除される前に、final_snapshot_identifier
の値を使用して DB スナップショットが作成されます。デフォルトはfalse
です。tags
– (オプション)リソースに割り当てるタグのマップ。プロバイダのdefault_tags
設定ブロックが存在する状態で設定された場合、一致するキーを持つタグはプロバイダ・レベルで定義されたものを上書きします。
IAM
# group definition
resource "aws_iam_group" "administrators" {
name = "administrators"
}
resource "aws_iam_policy_attachment" "administrators-attach" {
name = "administrators-attach"
groups = [aws_iam_group.administrators.name]
policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
}
# user
resource "aws_iam_user" "admin1" {
name = "admin1"
}
resource "aws_iam_user" "admin2" {
name = "admin2"
}
resource "aws_iam_group_membership" "administrators-users" {
name = "administrators-users"
users = [
aws_iam_user.admin1.name,
aws_iam_user.admin2.name,
]
group = aws_iam_group.administrators.name
}
- (注意)すでにユーザにpolicyをアタッチしている場合、
aws_iam_policy_attachment
を使用すると影響が出る可能性があります。代わりに、aws_iam_role_policy_attachment
,aws_iam_user_policy_attachment
,aws_iam_group_policy_attachment
を使用することが推奨されます。
IAM Role
resource "aws_iam_role" "s3-mybucket-role" {
name = "s3-mybucket-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_instance_profile" "s3-mybucket-role-instanceprofile" {
name = "s3-mybucket-role"
role = aws_iam_role.s3-mybucket-role.name
}
resource "aws_iam_role_policy" "s3-mybucket-role-policy" {
name = "s3-mybucket-role-policy"
role = aws_iam_role.s3-mybucket-role.id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::mybucket-c29df1",
"arn:aws:s3:::mybucket-c29df1/*"
]
}
]
}
EOF
}
aws_iam_role
IAMロールの設定。ヒアドキュメント(EOF (end of fileの略))ではなく、 jsonencode
を使っても良い。
aws_iam_instance_profile
IAMインスタンスプロファイルの設定。EC2インスタンスにIAMロールをアタッチする。
aws_iam_role_policy
IAMポリシー。IAMロールに紐づけるポリシー(権限)を設定する。
Auto Scaling
## autoscaling.tf
# resource "aws_launch_configuration" "example-launchconfig" {
# name_prefix = "example-launchconfig"
# image_id = var.AMIS[var.AWS_REGION]
# instance_type = "t2.micro"
# key_name = aws_key_pair.mykeypair.key_name
# security_groups = [aws_security_group.allow-ssh.id]
# }
resource "aws_launch_template" "example-launchtemplate" {
name_prefix = "example-launchtemplate"
image_id = var.AMIS[var.AWS_REGION]
instance_type = "t2.micro"
key_name = aws_key_pair.mykeypair.key_name
network_interfaces {
security_groups = [ aws_security_group.allow-ssh.id ]
}
}
resource "aws_autoscaling_group" "example-autoscaling" {
name = "example-autoscaling"
vpc_zone_identifier = [aws_subnet.main-public-1.id, aws_subnet.main-public-2.id]
# launch_configuration = aws_launch_configuration.example-launchconfig.name
min_size = 1
max_size = 2
health_check_grace_period = 300
health_check_type = "EC2"
force_delete = true
launch_template {
id = aws_launch_template.example-launchtemplate.id
version = "$Latest"
}
tag {
key = "Name"
value = "ec2 instance"
propagate_at_launch = true
}
}
aws_launch_configuration
(非推奨)autoscaling時の起動設定。使用は推奨されず、起動テンプレートの使用が推奨されます。aws_launch_configuration
を aws_autoscaling_group
と一緒に使う場合、name (Optional)
属性の代わりに name_prefix (Optional)
属性を使うことを推奨します。こうすることで、Terraformのライフサイクルが起動設定の変更を検知し、オートスケーリンググループを正しく更新できるようになります。
aws_autoscaling_group
オートスケーリンググループリソースを提供します。launch_configuration
、launch_template
、mixed_instances_policy
のいずれかを指定する必要があります。
aws_launch_template
EC2の起動テンプレートリソースを提供する。インスタンスやオートスケーリンググループの作成に使用できる。
(注意) AWSはEC2 Auto Scalingの一部である Launch Configurations
について、2022年12月31日以降にリリースされる新しいEC2機能や新しいEC2インスタンスタイプをサポートしないと発表しています。新しいEC2インスタンスタイプをAuto Scaling groupで使用するためには、Launch Templates
を使用する必要があります。
## autoscalingpolicy.tf
# scale up alarm
resource "aws_autoscaling_policy" "example-cpu-policy" {
name = "example-cpu-policy"
autoscaling_group_name = aws_autoscaling_group.example-autoscaling.name
adjustment_type = "ChangeInCapacity"
scaling_adjustment = "1"
cooldown = "300"
policy_type = "SimpleScaling"
}
resource "aws_cloudwatch_metric_alarm" "example-cpu-alarm" {
alarm_name = "example-cpu-alarm"
alarm_description = "example-cpu-alarm"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = "2"
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = "120"
statistic = "Average"
threshold = "30"
dimensions = {
"AutoScalingGroupName" = aws_autoscaling_group.example-autoscaling.name
}
actions_enabled = true
alarm_actions = [aws_autoscaling_policy.example-cpu-policy.arn]
}
# scale down alarm
resource "aws_autoscaling_policy" "example-cpu-policy-scaledown" {
name = "example-cpu-policy-scaledown"
autoscaling_group_name = aws_autoscaling_group.example-autoscaling.name
adjustment_type = "ChangeInCapacity"
scaling_adjustment = "-1"
cooldown = "300"
policy_type = "SimpleScaling"
}
resource "aws_cloudwatch_metric_alarm" "example-cpu-alarm-scaledown" {
alarm_name = "example-cpu-alarm-scaledown"
alarm_description = "example-cpu-alarm-scaledown"
comparison_operator = "LessThanOrEqualToThreshold"
evaluation_periods = "2"
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = "120"
statistic = "Average"
threshold = "5"
dimensions = {
"AutoScalingGroupName" = aws_autoscaling_group.example-autoscaling.name
}
actions_enabled = true
alarm_actions = [aws_autoscaling_policy.example-cpu-policy-scaledown.arn]
}
aws_autoscaling_policy
AutoScaling Scaling Policy リソースを提供します。オートスケーリングポリシーを使用する場合、アタッチされた aws_autoscaling_group
から desired_capacity
属性を省略することができます。手動または動的(ポリシーベース)スケーリングを選択するのが良い習慣です。
aws_cloudwatch_metric_alarm
CloudWatch Metric Alarmリソースを提供します。
ELB
## elb.tf
resource "aws_elb" "my-elb" {
name = "my-elb"
subnets = [aws_subnet.main-public-1.id, aws_subnet.main-public-2.id]
security_groups = [aws_security_group.elb-securitygroup.id]
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
health_check {
healthy_threshold = 2
unhealthy_threshold = 2
timeout = 3
target = "HTTP:80/"
interval = 30
}
cross_zone_load_balancing = true
connection_draining = true
connection_draining_timeout = 400
tags = {
Name = "my-elb"
}
}
Classic Load Balancerの設定。
Elastic Beanstalk
resource "aws_elastic_beanstalk_application" "app" {
name = "app"
description = "app"
}
# this automatically retrieves the latest solution stack
data "aws_elastic_beanstalk_solution_stack" "php-latest" {
most_recent = true
name_regex = "^64bit Amazon Linux (.*) running PHP 8.(.*)$"
}
resource "aws_elastic_beanstalk_environment" "app-prod" {
name = "app-prod"
application = aws_elastic_beanstalk_application.app.name
solution_stack_name = data.aws_elastic_beanstalk_solution_stack.php-latest.name
setting {
namespace = "aws:ec2:vpc"
name = "VPCId"
value = aws_vpc.main.id
}
setting {
namespace = "aws:ec2:vpc"
name = "Subnets"
value = "${aws_subnet.main-private-1.id},${aws_subnet.main-private-2.id}"
}
setting {
namespace = "aws:ec2:vpc"
name = "AssociatePublicIpAddress"
value = "false"
}
setting {
namespace = "aws:autoscaling:launchconfiguration"
name = "IamInstanceProfile"
value = aws_iam_instance_profile.app-ec2-role.name
}
setting {
namespace = "aws:autoscaling:launchconfiguration"
name = "SecurityGroups"
value = aws_security_group.app-prod.id
}
setting {
namespace = "aws:autoscaling:launchconfiguration"
name = "EC2KeyName"
value = aws_key_pair.mykeypair.id
}
setting {
namespace = "aws:autoscaling:launchconfiguration"
name = "InstanceType"
value = "t2.micro"
}
setting {
namespace = "aws:elasticbeanstalk:environment"
name = "ServiceRole"
value = aws_iam_role.elasticbeanstalk-service-role.name
}
setting {
namespace = "aws:ec2:vpc"
name = "ELBScheme"
value = "public"
}
setting {
namespace = "aws:ec2:vpc"
name = "ELBSubnets"
value = "${aws_subnet.main-public-1.id},${aws_subnet.main-public-2.id}"
}
setting {
namespace = "aws:elb:loadbalancer"
name = "CrossZone"
value = "true"
}
setting {
namespace = "aws:elasticbeanstalk:command"
name = "BatchSize"
value = "30"
}
setting {
namespace = "aws:elasticbeanstalk:command"
name = "BatchSizeType"
value = "Percentage"
}
setting {
namespace = "aws:autoscaling:asg"
name = "Availability Zones"
value = "Any 2"
}
setting {
namespace = "aws:autoscaling:asg"
name = "MinSize"
value = "1"
}
setting {
namespace = "aws:autoscaling:updatepolicy:rollingupdate"
name = "RollingUpdateType"
value = "Health"
}
setting {
namespace = "aws:elasticbeanstalk:application:environment"
name = "RDS_USERNAME"
value = aws_db_instance.mariadb.username
}
setting {
namespace = "aws:elasticbeanstalk:application:environment"
name = "RDS_PASSWORD"
value = aws_db_instance.mariadb.password
}
setting {
namespace = "aws:elasticbeanstalk:application:environment"
name = "RDS_DATABASE"
value = aws_db_instance.mariadb.db_name
}
setting {
namespace = "aws:elasticbeanstalk:application:environment"
name = "RDS_HOSTNAME"
value = aws_db_instance.mariadb.endpoint
}
}
Elastic BeanstalkはAWSへのデプロイやスケーリングを自動化してくれるツールです。
以上です。