使用地形创建IAM角色并将其附加到EC2



我有一个地形脚本来创建一个实例并为其附加一个角色。

一切都在按预期创造。

我面临的问题是,IAM角色正在创建,策略正在附加到该角色,但角色没有附加到实例。请帮忙。

我有以下地形脚本:

provider "aws" {
region = "ap-southeast-1"
}
terraform {
backend "s3" {
bucket = "example.com"
key    = "terraform/aws/ec2/xxxNNN/terraform.tfstate"
region = "ap-southeast-1"
}
}
resource "aws_iam_policy" "xxx_nodes_role_policy" {
name        = "xxx_nodes_role_policy"
description = "IAM Policy for XXX nodes"
policy      = "${file("xxx_nodes_role_policy.json")}"
}
resource "aws_iam_role" "ec2_role_for_xxx_nodes" {
name               = "ec2_role_for_xxx_nodes"
assume_role_policy = "${file("ec2_assumerolepolicy.json")}"
}
resource "aws_iam_role_policy_attachment" "xxx_nodes_role_policy_attachment" {
role       = "${aws_iam_role.ec2_role_for_xxx_nodes.name}"
policy_arn = "${aws_iam_policy.xxx_nodes_role_policy.arn}"
}
resource "aws_iam_instance_profile" "xxx_instance_profile" {
name  = "xxx_instance_profile"
role = "${aws_iam_role.ec2_role_for_xxx_nodes.name}"
}
variable "sgids" {
type = list(string)
default = [ "sg-XXX", "sg-XXX" ]
}
resource "aws_instance" "xxxNNN" {
ami           = "ami-063e3af9d2cc7fe94"
instance_type = "r5.large"
iam_instance_profile = "${aws_iam_instance_profile.xxx_instance_profile.name}"
availability_zone = "ap-southeast-1a"
key_name = "KKK"
vpc_security_group_ids = var.sgids
subnet_id = "subnet-XXX"
associate_public_ip_address = false
user_data = "${file("set-up.sh")}"
root_block_device {
volume_type = "gp2"
volume_size = "200"
delete_on_termination = true
}
tags = {
Name = "XXXXXXXXXXX/XXXNNN"
}
lifecycle {
prevent_destroy = true
}
}
resource "aws_eip" "XXXNNN" {
vpc = true
instance = "${aws_instance.xxxNNN.id}"
tags = {
Name = "XXXNNN"
}
lifecycle {
prevent_destroy = true
}
}

xxx_nodes_role_policy.json的内容如下:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:ap-southeast-1:0000:log-group:*",
"arn:aws:logs:ap-southeast-1:0000:log-group:production:*"
]
}
]
}

ec2_assumerolepolicy.json的内容如下:

{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}

一切都在按预期创造。

我面临的问题是,IAM角色正在创建,策略正在附加到该角色,但角色没有附加到实例。请帮忙。

编辑:在下面添加terraform apply输出:

aws_iam_policy.xxx_nodes_role_policy: Refreshing state... [id=arn:aws:iam::XXX:policy/xxx_nodes_role_policy]
aws_iam_role.ec2_role_for_xxx_nodes: Refreshing state... [id=ec2_role_for_xxx_nodes]
data.aws_iam_policy_document.instance-assume-role-policy: Refreshing state...
aws_iam_role_policy_attachment.xxx_nodes_role_policy_attachment: Refreshing state... [id=ec2_role_for_xxx_nodes-20200717102807715700000001]
aws_iam_instance_profile.xxx_instance_profile: Refreshing state... [id=xxx_instance_profile]
aws_instance.xxxNNN: Refreshing state... [id=i-XXX]
aws_eip.XXXNNN: Refreshing state... [id=eipalloc-XXX]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_eip.XXXNNN will be created
+ resource "aws_eip" "XXXNNN" {
+ allocation_id     = (known after apply)
+ association_id    = (known after apply)
+ customer_owned_ip = (known after apply)
+ domain            = (known after apply)
+ id                = (known after apply)
+ instance          = (known after apply)
+ network_interface = (known after apply)
+ private_dns       = (known after apply)
+ private_ip        = (known after apply)
+ public_dns        = (known after apply)
+ public_ip         = (known after apply)
+ public_ipv4_pool  = (known after apply)
+ tags              = {
+ "Name" = "XXXNNN"
}
+ vpc               = true
}
# aws_iam_policy.xxx_nodes_role_policy will be created
+ resource "aws_iam_policy" "xxx_nodes_role_policy" {
+ arn         = (known after apply)
+ description = "IAM Policy for XXX nodes"
+ id          = (known after apply)
+ name        = "xxx_nodes_role_policy"
+ path        = "/"
+ policy      = jsonencode(
{
+ Statement = [
+ {
+ Action   = [
+ "logs:CreateLogStream",
+ "logs:DescribeLogGroups",
+ "logs:DescribeLogStreams",
+ "logs:PutLogEvents",
]
+ Effect   = "Allow"
+ Resource = [
+ "arn:aws:logs:ap-southeast-1:XXX:log-group:*",
+ "arn:aws:logs:ap-southeast-1:XXX:log-group:production:*",
]
+ Sid      = "VisualEditor0"
},
]
+ Version   = "2012-10-17"
}
)
}
# aws_iam_role.ec2_role_for_xxx_nodes will be created
+ resource "aws_iam_role" "ec2_role_for_xxx_nodes" {
+ arn                   = (known after apply)
+ assume_role_policy    = jsonencode(
{
+ Statement = [
+ {
+ Action    = "sts:AssumeRole"
+ Effect    = "Allow"
+ Principal = {
+ Service = "ec2.amazonaws.com"
}
+ Sid       = ""
},
]
+ Version   = "2012-10-17"
}
)
+ create_date           = (known after apply)
+ force_detach_policies = false
+ id                    = (known after apply)
+ max_session_duration  = 3600
+ name                  = "ec2_role_for_xxx_nodes"
+ path                  = "/"
+ unique_id             = (known after apply)
}
# aws_iam_role_policy_attachment.xxx_nodes_role_policy_attachment will be created
+ resource "aws_iam_role_policy_attachment" "xxx_nodes_role_policy_attachment" {
+ id         = (known after apply)
+ policy_arn = (known after apply)
+ role       = "ec2_role_for_xxx_nodes"
}
# aws_instance.xxxNNN will be created
+ resource "aws_instance" "xxxNNN" {
+ ami                          = "ami-063e3af9d2cc7fe94"
+ arn                          = (known after apply)
+ associate_public_ip_address  = false
+ availability_zone            = "aws-region"
+ cpu_core_count               = (known after apply)
+ cpu_threads_per_core         = (known after apply)
+ get_password_data            = false
+ host_id                      = (known after apply)
+ iam_instance_profile         = "xxx_instance_profile"
+ id                           = (known after apply)
+ instance_state               = (known after apply)
+ instance_type                = "r5.large"
+ ipv6_address_count           = (known after apply)
+ ipv6_addresses               = (known after apply)
+ key_name                     = "key.name"
+ network_interface_id         = (known after apply)
+ outpost_arn                  = (known after apply)
+ password_data                = (known after apply)
+ placement_group              = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns                  = (known after apply)
+ private_ip                   = (known after apply)
+ public_dns                   = (known after apply)
+ public_ip                    = (known after apply)
+ security_groups              = (known after apply)
+ source_dest_check            = true
+ subnet_id                    = "subnet-XXX"
+ tags                         = {
+ "Name" = "XXXNNN"
}
+ tenancy                      = (known after apply)
+ user_data                    = "060b3d9c8929ff0f18bdd9fa151f5d982c256a78"
+ volume_tags                  = (known after apply)
+ vpc_security_group_ids       = [
+ "sg-XXX",
+ "sg-XXX",
]
+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name           = (known after apply)
+ encrypted             = (known after apply)
+ iops                  = (known after apply)
+ kms_key_id            = (known after apply)
+ snapshot_id           = (known after apply)
+ volume_id             = (known after apply)
+ volume_size           = (known after apply)
+ volume_type           = (known after apply)
}
+ ephemeral_block_device {
+ device_name  = (known after apply)
+ no_device    = (known after apply)
+ virtual_name = (known after apply)
}
+ metadata_options {
+ http_endpoint               = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens                 = (known after apply)
}
+ network_interface {
+ delete_on_termination = (known after apply)
+ device_index          = (known after apply)
+ network_interface_id  = (known after apply)
}
+ root_block_device {
+ delete_on_termination = true
+ device_name           = (known after apply)
+ encrypted             = (known after apply)
+ iops                  = (known after apply)
+ kms_key_id            = (known after apply)
+ volume_id             = (known after apply)
+ volume_size           = 200
+ volume_type           = "gp2"
}
}
Plan: 5 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_iam_policy.xxx_nodes_role_policy: Creating...
aws_iam_role.ec2_role_for_xxx_nodes: Creating...
aws_instance.xxxNNN: Creating...
aws_iam_role.ec2_role_for_xxx_nodes: Creation complete after 3s [id=ec2_role_for_xxx_nodes]
aws_iam_policy.xxx_nodes_role_policy: Creation complete after 4s [id=arn:aws:iam::XXX:policy/xxx_nodes_role_policy]
aws_iam_role_policy_attachment.xxx_nodes_role_policy_attachment: Creating...
aws_iam_role_policy_attachment.xxx_nodes_role_policy_attachment: Creation complete after 2s [id=ec2_role_for_xxx_nodes-20200717110045184300000001]
aws_instance.xxxNNN: Still creating... [10s elapsed]
aws_instance.xxxNNN: Still creating... [20s elapsed]
aws_instance.xxxNNN: Creation complete after 22s [id=i-XXX]
aws_eip.XXXNNN: Creating...
aws_eip.XXXNNN: Creation complete after 3s [id=eipalloc-XXX]
Apply complete! Resources: 5 added, 0 changed, 0 destroyed.

通过与其他人的讨论,我自己解决了这个问题。

RCA(根本原因分析(

因此,问题是第一次运行terraform apply时,创建了实例配置文件,但可能不是因为IAM权限不足,IAM角色无法附加到IAM实例配置文件。在terraform apply的所有后续执行中,terraform都使用了已经存在的实例配置文件(可能是因为我没有授予terraform用户销毁权限(。

我是如何发现这一点的

这是一件被忽视的简单事情。如果你在问题中计算我的terraform脚本中的资源数量,你会看到定义的资源数量是6,而在输出中,terraform总是用:

Apply complete! Resources: 5 added, 0 changed, 0 destroyed.

这就是我认为实例配置文件可能从未被删除的原因。

通过AWS CLI从IAM中删除实例配置文件,然后重新执行terraform apply修复了此问题。

有关IAM权限,您可以参考:https://iam.cloudonaut.io/reference/iam.html

在该URL的第页上执行查找并搜索InstanceProfile,然后为地形用户添加所需的权限。我把它们都加进去了。

相关内容

  • 没有找到相关文章

最新更新