I'm trying to figure out a "one command" approach to spin up spot instances with terraform.
I've managed to get this far:
resource "aws_iam_role" "spot_role" {
name_prefix = "spot_role_"
assume_role_policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "spotfleet.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_policy" "spot_policy" {
name_prefix = "spot_policy_"
description = "EC2 Spot Fleet Policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeImages",
"ec2:DescribeSubnets",
"ec2:RequestSpotInstances",
"ec2:TerminateInstances",
"ec2:DescribeInstanceStatus",
"ec2:CreateTags",
"ec2:RunInstances"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Condition": {
"StringEquals": {
"iam:PassedToService": [
"ec2.amazonaws.com",
"ec2.amazonaws.com.cn"
]
}
},
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:RegisterInstancesWithLoadBalancer"
],
"Resource": [
"arn:aws:elasticloadbalancing:*:*:loadbalancer/*"
]
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:RegisterTargets"
],
"Resource": [
"arn:aws:elasticloadbalancing:*:*:*/*"
]
}
]
}
EOF
}
locals {
role = aws_iam_role.spot_role
zone = join("", [var.region, "a"])
}
// -----------------------------------------------------------------------------
resource "aws_iam_role_policy_attachment" "spot_role_policy_attachment" {
role = local.role.name
policy_arn = aws_iam_policy.spot_policy.arn
}
// -----------------------------------------------------------------------------
resource "aws_security_group" "spot_security_group" {
name = "allow_ssh"
description = "Allow SSH inbound traffic"
vpc_id = aws_vpc.spot_vpc.id
ingress {
description = "SSH from anywhere"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "allow_ssh"
}
}
resource "aws_vpc" "spot_vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "spot_vpc"
}
}
resource "aws_subnet" "spot_subnet" {
vpc_id = aws_vpc.spot_vpc.id
cidr_block = "10.0.0.0/24"
map_public_ip_on_launch = true
availability_zone = local.zone
tags = {
Name = "spot_subnet"
}
}
resource "aws_spot_fleet_request" "spot_fleet_request" {
iam_fleet_role = local.role.arn
spot_price = "0.022"
target_capacity = 1
launch_specification {
instance_type = "r6g.medium"
ami = var.ami
key_name = var.key_name
subnet_id = aws_subnet.spot_subnet.id
availability_zone = local.zone
}
launch_specification {
instance_type = "a1.large"
ami = var.ami
key_name = var.key_name
subnet_id = aws_subnet.spot_subnet.id
availability_zone = local.zone
}
}
// -----------------------------------------------------------------------------
output "spot_fleet_request_id" {
value = aws_spot_fleet_request.spot_fleet_request.id
}
But I get the following error in the Spot Requests
-> Details
view:
spotFleetRequestConfigurationInvalid
r6g.medium, ami-0c582118883b46f4f, Linux/UNIX (Amazon VPC): The provided credentials do not have permission to create the service-linked role for EC2 Spot Instances.
EDIT
aws iam create-service-linked-role --aws-service-name spot.amazonaws.com
An error occurred (InvalidInput) when calling the CreateServiceLinkedRole operation: Service role name AWSServiceRoleForEC2Spot has been taken in this account, please try a different suffix.
arn:aws:iam::20XXXXXXX22:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot
has the following AWSEC2SpotServiceRolePolicy
attached
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:RunInstances"
],
"Resource": [
"*"
]
},
{
"Effect": "Deny",
"Action": [
"ec2:RunInstances"
],
"Resource": [
"arn:aws:ec2:*:*:instance/*"
],
"Condition": {
"StringNotEquals": {
"ec2:InstanceMarketType": "spot"
}
}
},
{
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": [
"*"
],
"Condition": {
"StringEquals": {
"iam:PassedToService": [
"ec2.amazonaws.com",
"ec2.amazonaws.com.cn"
]
}
}
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateTags"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:CreateAction": "RunInstances"
}
}
}
]
}
question from:
https://stackoverflow.com/questions/65861955/how-to-specify-iam-role-for-spot-fleet-role-with-terraform