如何使用 terraform 为现货车队角色指定 IAM 角色?

时间:2021-01-23 17:02:02

标签: amazon-web-services amazon-ec2 terraform amazon-iam

我正在尝试找出一种“一个命令”的方法来使用 terraform 启动现场实例。

我已经做到了这一点:

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
}

但我在 Spot Requests -> Details 视图中收到以下错误:

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.

编辑

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 附加了以下 AWSEC2SpotServiceRolePolicy

{
    "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"
                }
            }
        }
    ]
}

0 个答案:

没有答案