我正在尝试在AWS CloudFormation上创建一个具有EC2实例和2个S3存储桶的堆栈。我的脚本试图将策略分配给允许访问存储桶的EC2实例,但是无论我做什么,都不会分配权限。另外,根本不执行用户数据。
我尝试彻底测试EC2是否确实没有权限:CLI确认没有。我用制作文本文件的简单脚本替换了用户数据,但实际上并没有创建。 AWS Designer不提出任何投诉,并显示正确的模板结构。堆栈描述运行并执行没有错误,除了对S3存储桶的访问和用户数据不起作用(无警告)之外。
经过大量的手动编辑和非常仔细的检查文档之后,我意识到我应该使用更高级别的语言来完成此操作。因此,我尝试使用templateGenerator将脚本导入简单的python Troposphere脚本中。这会导致以下错误(到目前为止,其他任何地方都未创建其他错误,所有内容都默默地出错了,JSON语法验证器也没有任何抱怨):
TypeError: <class 'troposphere.iam.PolicyType'>: MickStorageS3BucketsPolicy.PolicyDocument is <class 'list'>, expected (<class 'dict'>,)
但是,很明显,我的PolicyDocument是字典类型的,而且我不明白如何将其解释为列表。我已经盯着这个看了好几个小时了,我可能对这个问题视而不见了,但是在这一点上,我真的很感谢任何帮助!!!!
安全组和入站流量设置正常运行,我的dockerized flask应用运行良好(在EC2上),但无法访问存储桶(尽管我必须通过SSH手动启动它,因为用户数据无法执行,我还尝试使用ec2元数据中的CFN-init段(在命令下)执行此操作,但是即使我尝试通过SSH连接后手动运行CFNinit,也不会执行任何操作。
这是我写的cloudformation模板:
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Attach IAM Role to an EC2",
"Parameters" : {
"KeyName" : {
"Description" : "EC2 Instance SSH Key",
"Type" : "AWS::EC2::KeyPair::KeyName",
"Default" : "MickFirstSSHKeyPair"
},
"InstanceType" : {
"Description" : "EC2 instance specs configuration",
"Type" : "String",
"Default" : "t2.micro",
"AllowedValues" : ["t2.micro", "t2.small", "t2.medium"]
}
},
"Mappings" : {
"AMIs" : {
"us-east-1" : {
"Name" : "ami-8c1be5f6"
},
"us-east-2" : {
"Name" : "ami-c5062ba0"
},
"eu-west-1" : {
"Name" : "ami-acd005d5"
},
"eu-west-3" : {
"Name" : "ami-05b93cd5a1b552734"
},
"us-west-2" : {
"Name" : "ami-0f2176987ee50226e"
},
"ap-southeast-2" : {
"Name" : "ami-8536d6e7"
}
}
},
"Resources" : {
"mickmys3storageinstance" : {
"Type" : "AWS::S3::Bucket",
"Properties" : {
}
},
"mickmys3processedinstance" : {
"Type" : "AWS::S3::Bucket",
"Properties" : {
}
},
"MickMainEC2" : {
"Type" : "AWS::EC2::Instance",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"config" : {
"files" : {
},
"commands" : {
}
}
}
},
"Properties" : {
"UserData": {
"Fn::Base64" : "echo 'Heelo ww' > ~/hello.txt"
},
"InstanceType" : {
"Ref" : "InstanceType"
},
"ImageId" : {
"Fn::FindInMap" : [
"AMIs",
{
"Ref" : "AWS::Region"
},
"Name"
]
},
"KeyName" : {
"Ref" : "KeyName"
},
"IamInstanceProfile" : {
"Ref" : "ListS3BucketsInstanceProfile"
},
"SecurityGroupIds" : [
{
"Ref" : "SSHAccessSG"
},
{
"Ref" : "PublicAccessSG"
}
],
"Tags" : [
{
"Key" : "Name",
"Value" : "MickMainEC2"
}
]
}
},
"SSHAccessSG" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Allow SSH access from anywhere",
"SecurityGroupIngress" : [
{
"FromPort" : "22",
"ToPort" : "22",
"IpProtocol" : "tcp",
"CidrIp" : "0.0.0.0/0"
}
],
"Tags" : [
{
"Key" : "Name",
"Value" : "SSHAccessSG"
}
]
}
},
"PublicAccessSG" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Allow HTML requests from anywhere",
"SecurityGroupIngress" : [
{
"FromPort" : "80",
"ToPort" : "80",
"IpProtocol" : "tcp",
"CidrIp" : "0.0.0.0/0"
}
],
"Tags" : [
{
"Key" : "Name",
"Value" : "PublicAccessSG"
}
]
}
},
"ListS3BucketsInstanceProfile" : {
"Type" : "AWS::IAM::InstanceProfile",
"Properties" : {
"Path" : "/",
"Roles" : [
{
"Ref" : "MickListS3BucketsRole"
}
]
}
},
"MickStorageS3BucketsPolicy" : {
"Type" : "AWS::IAM::Policy",
"Properties" : {
"PolicyName" : "MickStorageS3BucketsPolicy",
"PolicyDocument" : {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListObjectsInBucket",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::mickmys3storageinstance", "arn:aws:s3:::mickmys3storageinstance/*"
]
},
{
"Sid": "AllObjectActions",
"Effect": "Allow",
"Action": ["s3:*Object"],
"Resource": [
"arn:aws:s3:::mickmys3storageinstance", "arn:aws:s3:::mickmys3storageinstance/*"
]
}
]
},
"Roles" : [
{
"Ref" : "MickListS3BucketsRole"
}
]
}
},
"MickListS3BucketsRole" : {
"Type" : "AWS::IAM::Role",
"Properties" : {
"AssumeRolePolicyDocument": {
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Principal" : {
"Service" : ["ec2.amazonaws.com"]
},
"Action" : [
"sts:AssumeRole"
]
}
]
},
"Path" : "/"
}
}
},
"Outputs" : {
"EC2" : {
"Description" : "EC2 IP address",
"Value" : {
"Fn::Join" : [
"",
[
"ssh ec2-user@",
{
"Fn::GetAtt" : [
"MickMainEC2",
"PublicIp"
]
},
" -i ",
{
"Ref" : "KeyName"
},
".pem"
]
]
}
}
}
}
这是我的对流层脚本,在导入以上内容时会产生错误:
from troposphere import Ref, Template
import troposphere.ec2 as ec2
from troposphere.template_generator import TemplateGenerator
import json
with open("myStackFile.JSON") as f:
json_template = json.load(f)
template = TemplateGenerator(json_template)
template.to_json()
print(template.to_yaml())
我希望角色分配正确,用户数据也要执行。我希望对流层能够导入JSON,因为据我所知,它具有正确的语法和正确的类输入。我已经手工检查了许多小时,很多时间,我不确定如何继续使用CloudFormation脚本查找问题。将来(我会建议任何人都这样做),我将不再手动编辑JSON(或更糟糕的是,YAML)文件,而不会单独使用更高级别的工具。
感谢您的任何帮助/指标!
亲切的问候
答案 0 :(得分:0)
由于忘记了#!/bin/bash
,因此未执行您的用户数据。来自documentation:
用户数据外壳程序脚本必须以#!开头。字符和要读取脚本的解释器的路径(通常为/ bin / bash)。有关shell脚本的重要介绍,请参见Linux Documentation Project(tldp.org)上的BASH编程方法。
对于存储桶权限,我认为问题是您在策略中指定了CloudFormation资源名称,而不是实际的存储桶名称。如果要将存储桶实际命名为mickmys3storageinstance
,则需要:
"mickmys3storageinstance" : {
"Type" : "AWS::S3::Bucket",
"Properties" : {
"BucketName": "mickmys3storageinstance"
}
},
否则,您应该在策略中使用Ref
或Fn::Sub
来获取实际的存储桶名称。
{
"Sid": "ListObjectsInBucket",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
{"Fn::Sub": "${mickmys3storageinstance.Arn}"},
{"Fn::Sub": "${mickmys3storageinstance.Arn}/*"}
]
},