通过 IAM 角色使用 CF::Init 从我的 EC2 实例访问 S3 存储桶不起作用

通过 IAM 角色使用 CF::Init 从我的 EC2 实例访问 S3 存储桶不起作用

我有一个 CloudFormation 模板,正在使用它来设置 ECS 集群,并且我正尝试使用 ASG 上的 CloudFormation::Init 将一些配置文件放到框中,然后将它们从 S3 中拉出。

"ECSASGLaunchConfiguration": {
  "Type": "AWS::AutoScaling::LaunchConfiguration",
  "Metadata": {
    "AWS::CloudFormation::Authentication": {
      "S3AccessCreds": {
        "type": "S3",
        "roleName": {
          "Ref": "ECSEC2InstanceIAMRole"
        }
      }
    },
    "AWS::CloudFormation::Init": {
      "config": {
        "packages": {
        },
        "groups": {
        },
        "users": {
        },
        "sources": {
        },
        "files": {
          "/etc/dd-agent/conf.d/nginx.yaml": {
            "source": "https://s3.amazonaws.com/foobar/scratch/nginx.yaml",
            "mode": "000644",
            "owner": "root",
            "group": "root"
          },
          "/etc/dd-agent/conf.d/docker_daemon.yaml": {
            "source": "https://s3.amazonaws.com/foobar/scratch/docker_daemon.yaml",
            "mode": "000644",
            "owner": "root",
            "group": "root"
          }
        },
        "commands": {
        },
        "services": {
        }
      }
    }
  },

为此,我在为 EC2 实例创建的角色中添加了一条内联策略,该策略应允许从实例进行所有 S3 访问。

"ECSEC2InstanceIAMRole": {
  "Type": "AWS::IAM::Role",
  "Properties": {
    "AssumeRolePolicyDocument": {
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Service": [
              "ec2.amazonaws.com"
            ]
          },
          "Action": [
            "sts:AssumeRole"
          ]
        }
      ]
    },
    "ManagedPolicyArns": [
      "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role",
      "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
    ],
    "Path": "/",
    "Policies": [
      {
        "PolicyName": "otxS3access",
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": "s3:ListAllMyBuckets",
              "Resource": "arn:aws:s3:::*"
            },
            {
              "Effect": "Allow",
              "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
              ],
              "Resource": "arn:aws:s3:::foobar"
            },
            {
              "Effect": "Allow",
              "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
              ],
              "Resource": "arn:aws:s3:::foobar/*"
            }
          ]
        }
      }
    ]
  }
},
"ECSEC2InstanceIAMProfile": {
  "Type": "AWS::IAM::InstanceProfile",
  "Properties": {
    "Path": "/",
    "Roles": [
      {
        "Ref": "ECSEC2InstanceIAMRole"
      }
    ]
  }
},

但它不起作用。我在日志中找不到错误(或其他任何内容)。当我手动尝试从实例中卷曲它时,它也不起作用,“ AccessDenied...”

在这种情况下,存储桶本身“foobar”除了不公开之外没有任何特殊权限,只是标准帐户名称单一受让人。

知道我做错了什么吗?

答案1

我发现了问题。问题中的所有 CloudFormation 都很好,并且按预期工作。问题在于我在 ASG 的启动配置中设置的实例用户数据中运行 cfn-init - 它不起作用,所以它没有执行初始化操作。感谢 @Rob-d,你的评论让我走上了可执行文件级别的道路。

使这一切发挥作用的另一个神奇部分是:

    "UserData": {
      "Fn::Base64": {
        "Fn::Join": [
          "",
          [
            "#!/bin/bash\n",
            "cat > /etc/ecs/ecs.config <<EOF\n",
            "ECS_CLUSTER=",
            {
              "Ref": "ECSCluster"
            },
            "\n",
            "ECS_ENGINE_AUTH_TYPE=docker\n",
            "ECS_ENGINE_AUTH_DATA={REDACTED}\n",
            "EOF\n",
            "yum -y install aws-cfn-bootstrap\n",
            "# Install the files and packages from the metadata\n",
            "/opt/aws/bin/cfn-init -v ",
            "         --stack ",
            {
              "Ref": "AWS::StackName"
            },
            "         --resource ECSASGLaunchConfiguration ",
            "         --region ",
            {
              "Ref": "AWS::Region"
            },
            "\n",
            "/opt/aws/bin/cfn-signal -e -0 ",
            "         --stack ",
            {
              "Ref": "AWS::StackName"
            },
            "         --resource ECSAutoScalingGroup ",
            "         --region ",
            {
              "Ref": "AWS::Region"
            },
            "\n",
            "\n"
          ]
        ]
      }
    }

相关内容