Je veux créer un ARN de manière dynamique dans mon fichier, mais je dois obtenir mon AccountId actuel. Comment puis-je y accéder en tant que variable?
Par exemple:
example: arn:aws:states:${region}:${accountId}:stateMachine:${self:service}-${self:custom.stage}-example
Quelle est la bonne façon de référencer les region
et accountId
actuels?
Modifier: (solution)
Je ne suis pas super content de cette solution en raison de la laideur et de la verbosité du Fn::Join
solution mais ce que j'ai fini par faire est de faire un arns.yml
fichier qui a tout cela en un seul endroit puis référence ensuite par variable ailleurs.
# arns.yml
example:
Fn::Join:
- ":"
- - arn
- aws
- states
- Ref: AWS::Region
- Ref: AWS::AccountId
- stateMachine
- ${self:service}-${self:custom.stage}-example
Alors:
# serverless.yml
custom:
stage: "${opt:stage, self:provider.stage}"
functions:
foo:
handler: handler.foo
environment:
example_arn: ${file(arns.yml):example}
Edit 2: (Meilleure solution)
Cela peut sembler boiteux mais la solution avec laquelle j'ai fini par le faire est de le coder en dur dans mes variables personnalisées. J'ai en fait deux comptes et j'utilise une étape de construction personnalisée pour copier les deux fichiers avec des paramètres spécifiques au compte comme ceci:
account.stag.yml
account.prod.yml
Chaque fichier peut ressembler à ceci:
# account.stag.yml
account: 123456789
region: ${opt:region, "us-east-1"}
domain: mycompany.qa
Lorsque je crée, je spécifie un compte et j'utilise gulp pour faire tout mon bâtiment:
gulp build --account stag
Ensuite, cela renomme les paramètres spécifiques à mon compte en
build/account.yml
Et je peux le référencer dans mon serverless.yml comme ceci:
# build/serverless.yml
custom: ${file(account.yml)}
functions:
foo:
handler: handler.foo
environment:
example_arn: arn:aws:states:${self:custom.region}:${self:custom.account}:${self:service}-${opt:stage}-example
Il y a un plugin sans serveur pratique https://www.npmjs.com/package/serverless-pseudo-parameters qui ajoute la possibilité de référencer des paramètres aws tels que la région et l'ID de compte que je viens de commencer à utiliser à beaucoup de succès.
Sans serveur lui-même ne peut pas référencer ces variables car celles-ci sont définies dans CloudFormation, mais ne sont pas exposées dans sans serveur.
Si vous en avez besoin dans la section des ressources, vous pouvez y accéder directement via l'appel "Ref".
pseudo-variables AWS CloudFormation
Si vous avez besoin de ces variables comme variables d'environnement de fonction, vous pouvez remplacer le code de fonction généré sans serveur par le code CloudFormation.
Donc, pour y parvenir, vous devez modifier votre serverless.yml par le modèle suivant.
functions:
hello:
handler: handler.hello
resources:
Resources:
HelloLambdaFunction:
Type: AWS::Lambda::Function
Properties:
Environment:
Variables:
accountId:
Ref: AWS::AccountId
region:
Ref: AWS::Region
arn:
Fn::Join:
- ""
- - "arn:aws:states:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- ":stateMachine:"
- ${self:service}
- "-"
- ${self:custom.stage}
- "-example"
AWS CloudFormation propose certaines variables comme AWS::AccountId
et AWS::Region
, mais vous ne pouvez pas les utiliser dans le fichier serverless.yml comme ${AWS::AccountId}
. Ceux-ci ne sont pas pris en charge.
@ réponse jens a raison. Vous devez utiliser la syntaxe CloudFormation. Dans l'exemple ci-dessous, je propose une autre façon d'utiliser CloudFormation.
service: testing-aws-account-id
provider:
name: aws
runtime: nodejs4.3
region: us-east-1
iamRoleStatements:
- Effect: "Allow"
Action:
- "iot:Publish"
Resource: 'Fn::Join: ["", [ "aws:iot:", { "Ref": "AWS::Region" }, ":", { Ref: "AWS::AccountId" }, ":topic/foo" ]]'
functions:
publishIot:
handler: handler.publishIot
La ligne:
Resource: 'Fn::Join: ["", [ "aws:iot:", { "Ref": "AWS::Region" }, ":", { Ref: "AWS::AccountId" }, ":topic/foo" ]]'
revient à coder en dur la région et l'ID de compte:
Resource: "arn:aws:iot:us-east-1:1234567890:topic/foo"
Comme déjà répond , le Framework sans serveur n'offre actuellement aucun moyen de récupérer l'ID de compte. Vous devez utiliser la syntaxe CloudFormation pour cela.
Cependant, si vous définissez une stratégie d'accès IAM, vous n'avez pas besoin de l'ID de compte AWS. Placez simplement *
où vous mettriez le numéro de compte. L'ID de compte est nécessaire dans les cas suivants:
Regardez le fichier serverless.yml suivant:
service: testing-aws-account-id
provider:
name: aws
runtime: nodejs4.3
region: us-east-1
iamRoleStatements:
- Effect: "Allow"
Action:
- "iot:Publish"
Resource: "arn:aws:iot:${self:provider.region}:*:topic/foo"
functions:
publishIot:
handler: handler.publishIot
Ça marche. J'utilise *
au lieu de mon numéro de compte et j'utilise ${self:provider.region}
pour référencer la région que j'ai définie dans mon fournisseur (us-east-1).