Почему этот скрипт шаблона CloudFormation не работает? - PullRequest
1 голос
/ 01 июля 2019

Я пытаюсь создать стек в AWS CloudFormation с экземпляром EC2 и 2 корзинами S3. Мой сценарий пытается назначить Политику экземпляру EC2, который разрешает доступ к хранилищу, но независимо от того, что я делаю, права не назначаются. Кроме того, пользовательские данные не выполняются вообще.

Я попытался провести тщательное тестирование, если у EC2 действительно нет прав: CLI подтвердил, что его нет. Я заменил пользовательские данные простым скриптом, создающим текстовый файл, он действительно не создан. AWS Designer не предъявляет претензий и показывает правильную структуру шаблона. Описание стека выполняется и выполняется без ошибок, за исключением доступа к хранилищу S3, когда пользовательские данные не работают (без предупреждений).

После МНОГО ручного редактирования и очень тщательной проверки документации я понял, что должен был сделать это на языке более высокого уровня. Поэтому я попытался импортировать скрипт в простой скрипт Python Troposphere, используя templateGenerator. Это приводит к следующей ошибке (на данный момент нигде не создаются другие ошибки, все просто молча идет не так, валидаторы синтаксиса JSON также не имеют претензий):

TypeError: <class 'troposphere.iam.PolicyType'>: MickStorageS3BucketsPolicy.PolicyDocument is <class 'list'>, expected (<class 'dict'>,)

Однако, очевидно, что мой PolicyDocument относится к словарю типов, и я не понимаю, как его можно интерпретировать как список. Я смотрю на это уже много часов, возможно, я стал слепым к этой проблеме, но я действительно был бы очень признателен за любую помощь на данный момент !!!!

Настройки группы безопасности и входящего трафика работают должным образом, мое приложение с докерской флягой работает нормально (на EC2), но просто не может получить доступ к корзине (хотя я должен запустить его вручную через SSH, потому что userdata не будет выполняться, Я также попытался сделать это, используя сегмент CFN-init в метаданных ec2 (под командами), но ничего не выполняется, даже если я пытаюсь запустить CFNinit вручную после подключения по SSH).

Это шаблон облачной информации, который я написал:

{
  "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) вручную, а буду использовать исключительно инструменты более высокого уровня.

Спасибо за ЛЮБУЮ помощь / указатели!

С уважением

1 Ответ

0 голосов
/ 01 июля 2019

Ваши данные пользователя не выполнены, потому что вы забыли #!/bin/bash.Из документации :

Сценарии оболочки пользовательских данных должны начинаться с #!символы и путь к интерпретатору, который вы хотите прочитать в скрипте (обычно / bin / bash).Отличное введение в сценарии оболочки см. В руководстве по программированию на BASH в Проекте документации Linux (tldp.org).

Что касается разрешений сегмента, я считаю, что проблема заключается в указании ресурса 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}/*"}
                    ]
                },  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...