2015-08-23 4 views
3

Je n'arrive pas à comprendre comment configurer un Couche OpsWorks en utilisant un cluster ECS dans CloudFormation. La création de ma couche échoue en raison de l'erreur ci-dessous, mais il ne semble pas y avoir de moyen clair d'enregistrer le cluster avec la pile dans le modèle. J'ai essayé d'ajouter EcsClusterArn à la fois Stack et Layer, mais cela n'a pas fonctionné. L'API a une commande mais je voudrais tout contenir dans mon template.Comment enregistrer un cluster ECS avec Opsworks Stack dans CloudFormation?

Erreur:

Attributes - EcsClusterArn: XXX must be registered to the layer's stack first. 

Snippet du modèle:

"ecsCluster" : { 
    "Type" : "AWS::ECS::Cluster" 
}, 
... 
"opsworksStack" : { 
    "Type" : "AWS::OpsWorks::Stack", 
    "Properties" : { 
    "Name" : "my-stack", 
    "ServiceRoleArn" : { 
     "Fn::Join" : [ "", [ "arn:aws:iam::", { 
     "Ref" : "AWS::AccountId" 
     }, ":role/", { 
     "Ref" : "ServiceRole" 
     } ] ] 
    }, 
    "DefaultInstanceProfileArn" : { 
     "Fn::Join" : [ "", [ "arn:aws:iam::", { 
     "Ref" : "AWS::AccountId" 
     }, ":instance-profile/", { 
     "Ref" : "InstanceRole" 
     } ] ] 
    }, 
    "UseOpsworksSecurityGroups" : "false", 
    "ChefConfiguration" : { 
     "BerkshelfVersion" : "3.3.0", 
     "ManageBerkshelf" : "true" 
    }, 
    "ConfigurationManager" : { 
     "Name" : "Chef", 
     "Version" : "11.10" 
    } 
    } 
}, 
"opsworksLayer" : { 
    "Type" : "AWS::OpsWorks::Layer", 
    "DependsOn" : "ecsCluster", 
    "Properties" : { 
    "StackId" : { 
     "Ref" : "opsworksStack" 
    }, 
    "Type" : "ecs-cluster", 
    "Name" : "my-layer", 
    "Shortname" : "my-layer", 
    "Attributes" : { 
     "EcsClusterArn" : { 
     "Fn::Join" : [ "", [ "arn:aws:ecs:", { 
      "Ref" : "AWS::Region" 
     }, ":", { 
      "Ref" : "AWS::AccountId" 
     }, ":cluster/", { 
      "Ref" : "ecsCluster" 
     } ] ] 
     } 
    }, 
    "CustomSecurityGroupIds" : [ { 
     "Ref" : "ec2DefaultSecurityGroup" 
    } ], 
    "EnableAutoHealing" : "true", 
    "AutoAssignElasticIps" : "false", 
    "AutoAssignPublicIps" : "false", 
    "InstallUpdatesOnBoot" : "true" 
    } 
} 

Merci, Thien

+0

Salut Thien, je me demande si vous étiez en mesure de résoudre ce problème? Je suis également confronté à la même erreur lors de la connexion d'un cluster ECS à une pile Opsworks. –

+0

@ManishJoshi J'avais créé un cas avec Amazon et ils avaient résolu le bug le 24 février 2016.Il devrait fonctionner maintenant en utilisant "EcsClusterArn" dans la section "Attributs" pour le OpsWorks Layer comme décrit dans la documentation. – Thien

+0

Merci @Thien, Malheureusement, il ne fonctionne toujours pas pour moi, j'ai soulevé des cas avec Amazon, ils sont toujours à la recherche. Je vais laisser les gens ici savoir si je trouve une autre raison pour cette erreur aussi :) –

Répondre

0

Selon l'article Adding an ECS Cluster Layer to a Stack, Association d'un cluster avec une pile nécessite deux opérations:

[...] registering the cluster with the stack and then creating the associated layer. The AWS OpsWorks console combines these steps; layer creation automatically registers the specified cluster. If you use the AWS OpsWorks API, CLI, or SDK, you must use separate operations to register the cluster and create the associated layer. [emphasis mine]

état Vous vous essayé d'ajouter EcsClusterArn à la fois Stack et couche, mais cela ne fonctionne pas, mais le message d'erreur confirme que le cluster Amazon ECSdoit être enregistré à la pile de la première couche et votre modèle d'échantillon est manquant cet aspect en fait? Au cas où, vous pourriez simplement devoir répéter votre resp. fragment de AWS::OpsWorks::Layer dans les AWS::OpsWorks::Stack aussi:

"Attributes" : { 
     "EcsClusterArn" : { 
     "Fn::Join" : [ "", [ "arn:aws:ecs:", { 
      "Ref" : "AWS::Region" 
     }, ":", { 
      "Ref" : "AWS::AccountId" 
     }, ":cluster/", { 
      "Ref" : "ecsCluster" 
     } ] ] 
     } 
    }, 
+0

Ouais c'est ce que j'avais essayé avant, mais l'a enlevé de ce que j'ai posté. Je viens de vérifier et cela me donne toujours la même erreur. – Thien

2

Mon impression est que l'enregistrement du groupe à la pile échoue. Pour contourner ce problème, j'ai implémenté une fonction lambda pour effectuer l'enregistrement manuellement. J'ai posté un exemple de gabarit sur github: https://github.com/arjenderijke/aws-cloud-examples/blob/master/cloudformation/opsworks/opsworks-ecs-layer.template

Le gabarit de cloud contient un exemple complet de pile opsworks avec une couche ecs et les autres ressources minimales requises. La pile ne peut normalement pas être créée, car le cluster ecs n'est pas automatiquement enregistré. Pour contourner ce problème, le modèle implémente une ressource personnalisée qui exécute une fonction aws lambda. Cette fonction enregistre le cluster dans la pile. En utilisant cette ressource personnalisée, l'erreur ne se produit plus.

"OpsworksRegisterCluster": { 
    "Type": "AWS::Lambda::Function", 
    "Properties": { 
    "Handler": "index.lambda_handler", 
    "Role": { "Fn::GetAtt" : ["LambdaExecutionRole", "Arn"] }, 
    "Code": { 
     "ZipFile": { "Fn::Join": ["\n", [ 
     "import boto3", 
     "import json", 
     "import cfnresponse", 
     "ecsclient = boto3.client('ecs')", 
     "opsworksclient = boto3.client('opsworks',", 
     " region_name='us-east-1',", 
     " endpoint_url='https://opsworks.us-east-1.amazonaws.com')", 
     "def lambda_handler(event, context):", 
     " try:", 
     " if (event['RequestType'] == 'Create'):", 
     "  ecscluster = ecsclient.describe_clusters(clusters=[", 
     "  event['ResourceProperties']['EcsClusterName']])", 
     "  response = opsworksclient.register_ecs_cluster(", 
     "  EcsClusterArn=ecscluster['clusters'][0]['clusterArn'],", 
     "  StackId=event['ResourceProperties']['OpsworksStackId']", 
     "  )", 
     "  responseData = {}", 
     "  responseData['data'] = response['EcsClusterArn']", 
     "  cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, \"CustomResourcePhysicalID\")", 
     " else:", 
     "  responseData = {}", 
     "  cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, \"CustomResourcePhysicalID\")", 
     " except Exception as e:", 
     " responseData = {}", 
     " responseData['error'] = e.message", 
     " cfnresponse.send(event, context, cfnresponse.FAILED, responseData, \"CustomResourcePhysicalID\")" 
     ]]} 
    }, 
    "Runtime": "python2.7", 
    "Timeout": "10" 
    } 
}, 
1

Juste pour la connaissance de tout le monde, je faisais face à ce problème avec AWS CloudFormation quelques jours en arrière et je soulevé un cas avec Amazon pour cela.

Il semble que ce problème existe toujours dans leur API (comme indiqué par Thien dans les commentaires, ce bug devait être résolu en février 2016) et il n'a pas été résolu, pas sûr parce que j'utilise des piles imbriquées que ce problème existe (peut-être dans un seul modèle ce n'est pas le cas, je n'ai pas essayé cela).

Les personnes AWS m'ont demandé d'utiliser la fonction lambda pour résoudre ce problème et il s'agit d'une fonction lambda très similaire à celle fournie par @Arjen ci-dessus. Donc, si vous faites face à ce problème, veuillez utiliser la fonction lambda fournie ci-dessus.

Merci, Manish