Existe-t-il un moyen de définir des raccourcis pour les valeurs fréquemment utilisées dérivées des paramètres du modèle CloudFormation?
Par exemple - J'ai un script qui crée une pile de projet Multi-AZ avec le nom ELB project
et deux instances derrière l'ELB appelées project-1
et project-2
. Je passe uniquement le ELBHostName
paramètre au modèle et plus tard je l'utilise pour construire:
"Fn::Join": [
".", [
{ "Fn::Join": [ "", [ { "Ref": "ELBHostName" }, "-1" ] ] },
{ "Ref": "EnvironmentVersioned" },
{ "Ref": "HostedZone" }
]
]
Cette construction ou très similaire est répétée plusieurs fois dans le modèle - pour créer le nom d'hôte EC2, les enregistrements Route53, etc.
Au lieu de répéter cela encore et encore, je voudrais affecter la sortie de cela Fn::Join
à une variable quelconque et ne me référer qu'à cela, tout comme je le peux avec l' "Ref":
instruction.
Idéalement, quelque chose comme:
Var::HostNameFull = "Fn::Join": [ ... ]
...
{ "Name": { "Ref": "Var::HostNameFull" } }
ou quelque chose de similaire simple.
Est-ce possible avec Amazon CloudFormation?
Réponses:
Je cherchais la même fonctionnalité. L'utilisation d'une pile imbriquée comme SpoonMeiser l'a suggéré m'est venue à l'esprit, mais j'ai réalisé que ce dont j'avais réellement besoin, c'était de fonctions personnalisées. Heureusement, CloudFormation permet d'utiliser AWS :: CloudFormation :: CustomResource qui, avec un peu de travail, permet de faire exactement cela. Cela semble exagéré pour les seules variables (quelque chose que je dirais qui aurait dû être dans CloudFormation en premier lieu), mais il fait le travail et, en plus, permet toute la flexibilité de (faites votre choix de python / nœud /Java). Il convient de noter que les fonctions lambda coûtent de l'argent, mais nous parlons ici de quelques centimes, sauf si vous créez / supprimez vos piles plusieurs fois par heure.
La première étape consiste à créer une fonction lambda sur cette page qui ne fait que prendre la valeur d'entrée et la copier dans la sortie. Nous pourrions avoir la fonction lambda faire toutes sortes de choses folles, mais une fois que nous avons la fonction d'identité, tout le reste est facile. Alternativement, nous pourrions avoir la fonction lambda en cours de création dans la pile elle-même. Étant donné que j'utilise plusieurs piles dans un compte, j'aurais tout un tas de fonctions et de rôles lambda restants (et toutes les piles doivent être créées avec
--capabilities=CAPABILITY_IAM
, car elles ont également besoin d'un rôle.Créer une fonction lambda
index.handler
Copiez-collez ensuite le code ci-dessous dans le champ de code. Le haut de la fonction est le code du module python cfn-response , qui n'est installé automatiquement que si la fonction lambda est créée via CloudFormation, pour une raison étrange. La
handler
fonction est assez explicite.Vous pouvez maintenant tester la fonction lambda en sélectionnant le bouton "Test" et sélectionnez "CloudFormation Create Request" comme exemple de modèle. Vous devriez voir dans votre journal que les variables qui y sont alimentées sont retournées.
Utiliser une variable dans votre modèle CloudFormation
Maintenant que nous avons cette fonction lambda, nous pouvons l'utiliser dans les modèles CloudFormation. Prenez d'abord note de la fonction lambda Arn (allez sur la page d'accueil lambda , cliquez sur la fonction qui vient d'être créée, l'Arn devrait être en haut à droite, quelque chose comme
arn:aws:lambda:region:12345:function:CloudFormationIdentity
).Maintenant, dans votre modèle, dans la section des ressources, spécifiez vos variables comme:
Je spécifie d'abord une
Identity
variable qui contient l'Arn pour la fonction lambda. Mettre ceci dans une variable ici, signifie que je n'ai qu'à le spécifier une fois. Je fais toutes mes variables de typeCustom::Variable
. CloudFormation vous permet d'utiliser n'importe quel nom de type commençant parCustom::
pour des ressources personnalisées.Notez que la
Identity
variable contient deux fois Arn pour la fonction lambda. Une fois pour spécifier la fonction lambda à utiliser. La deuxième fois comme valeur de la variable.Maintenant que j'ai la
Identity
variable, je peux définir de nouvelles variables en utilisantServiceToken: !GetAtt [Identity, Arn]
(je pense que le code JSON devrait être quelque chose comme"ServiceToken": {"Fn::GetAtt": ["Identity", "Arn"]}
). Je crée 2 nouvelles variables, chacune avec 2 champs: Name et Arn. Dans le reste de mon modèle, je peux l'utiliser!GetAtt [ClientBucketVar, Name]
ou!GetAtt [ClientBucketVar, Arn]
quand j'en ai besoin.Un mot d'avertissement
Lorsque vous travaillez avec des ressources personnalisées, si la fonction lambda se bloque, vous êtes bloqué entre 1 et 2 heures, car CloudFormation attend une réponse de la fonction (bloquée) pendant une heure avant d'abandonner. Par conséquent, il peut être utile de spécifier un court délai d'attente pour la pile lors du développement de votre fonction lambda.
la source
cloudformation-tool
gemme), donc j'emballe la création lambda dans le modèle et peut ensuite l'utiliser directement au lieu de créer laIdentity
ressource personnalisée. Voir ici pour mon code: gist.github.com/guss77/2471e8789a644cac96992c4102936fb3Je n'ai pas de réponse, mais je voulais souligner que vous pouvez vous épargner beaucoup de douleur en utilisant
Fn::Sub
à la place deFn::Join
Remplace
la source
Non, je l'ai essayé, mais est venu vide. La manière qui me paraissait logique était de créer une entrée Mappings appelée "CustomVariables" et de faire en sorte qu'elle héberge toutes mes variables. Cela fonctionne pour les chaînes simples, mais vous ne pouvez pas utiliser Intrinsics (Refs, Fn :: Joins, etc.) dans les mappages .
Travaux:
Ne fonctionnera pas:
Ce n'est qu'un exemple. Vous ne mettriez pas une référence autonome dans une variable.
la source
Vous pouvez utiliser une pile imbriquée qui résout toutes vos variables dans ses sorties, puis utiliser
Fn::GetAtt
pour lire les sorties de cette pilela source
Vous pouvez utiliser des modèles imbriqués dans lesquels vous "résolvez" toutes vos variables dans le modèle externe et les transmettez à un autre modèle.
la source