Outputs et Exports
Introduction
Les Outputs permettent d'exposer des valeurs importantes de votre stack. Les Exports permettent de partager ces valeurs avec d'autres stacks.
Outputs
Syntaxe de base
Outputs:
OutputName:
Description: Description de l'output
Value: ValeurOuRéférence
Condition: ConditionName # Optionnel
Export: # Optionnel
Name: ExportName
Exemples simples
Resources:
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
MyInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
ImageId: ami-12345678
Outputs:
# Output simple avec !Ref
VPCId:
Description: ID du VPC créé
Value: !Ref MyVPC
# Output avec !GetAtt
InstancePublicIP:
Description: IP publique de l'instance
Value: !GetAtt MyInstance.PublicIp
# Output avec !Sub
InstanceURL:
Description: URL de l'application
Value: !Sub 'http://${MyInstance.PublicDnsName}:8080'
# Output conditionnel
DatabaseEndpoint:
Condition: CreateDatabase
Description: Endpoint de la base de données
Value: !GetAtt Database.Endpoint.Address
Outputs multiples valeurs
Outputs:
# Liste en chaîne
SubnetIds:
Description: IDs des subnets
Value: !Join
- ','
- - !Ref Subnet1
- !Ref Subnet2
- !Ref Subnet3
# JSON pour structures complexes
StackInfo:
Description: Informations de la stack
Value: !Sub |
{
"stackName": "${AWS::StackName}",
"region": "${AWS::Region}",
"vpcId": "${VPC}",
"environment": "${Environment}"
}
Exports (Cross-Stack References)
Les exports permettent de partager des valeurs entre stacks.
Créer un export
# Stack: network-stack
Outputs:
VPCId:
Description: ID du VPC
Value: !Ref VPC
Export:
Name: !Sub '${AWS::StackName}-VPCId'
PublicSubnetIds:
Description: IDs des subnets publics
Value: !Join [',', [!Ref PublicSubnet1, !Ref PublicSubnet2]]
Export:
Name: !Sub '${AWS::StackName}-PublicSubnets'
PrivateSubnetIds:
Description: IDs des subnets privés
Value: !Join [',', [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
Export:
Name: !Sub '${AWS::StackName}-PrivateSubnets'
Importer une valeur
# Stack: application-stack
Resources:
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Subnets: !Split
- ','
- !ImportValue network-stack-PublicSubnets
SecurityGroups:
- !Ref ALBSecurityGroup
AppSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !ImportValue network-stack-VPCId
GroupDescription: Security group for application
Syntaxe ImportValue
# Forme longue
Value: !ImportValue
Fn::Sub: '${NetworkStackName}-VPCId'
# Forme courte avec nom fixe
Value: !ImportValue network-stack-VPCId
# Avec Sub pour nom dynamique
Value: !ImportValue
!Sub '${NetworkStackName}-VPCId'
Pattern : Stack Network + Application
Stack Network (parent)
AWSTemplateFormatVersion: '2010-09-09'
Description: Stack réseau partagée
Parameters:
Environment:
Type: String
Default: dev
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-vpc'
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: true
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.2.0/24
AvailabilityZone: !Select [1, !GetAZs '']
MapPublicIpOnLaunch: true
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.11.0/24
AvailabilityZone: !Select [0, !GetAZs '']
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.12.0/24
AvailabilityZone: !Select [1, !GetAZs '']
Outputs:
VPCId:
Description: VPC ID
Value: !Ref VPC
Export:
Name: !Sub '${AWS::StackName}-VPCId'
VPCCidr:
Description: VPC CIDR
Value: !GetAtt VPC.CidrBlock
Export:
Name: !Sub '${AWS::StackName}-VPCCidr'
PublicSubnets:
Description: Public subnet IDs
Value: !Join [',', [!Ref PublicSubnet1, !Ref PublicSubnet2]]
Export:
Name: !Sub '${AWS::StackName}-PublicSubnets'
PrivateSubnets:
Description: Private subnet IDs
Value: !Join [',', [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
Export:
Name: !Sub '${AWS::StackName}-PrivateSubnets'
AvailabilityZones:
Description: AZs utilisées
Value: !Join
- ','
- - !GetAtt PublicSubnet1.AvailabilityZone
- !GetAtt PublicSubnet2.AvailabilityZone
Export:
Name: !Sub '${AWS::StackName}-AZs'
Stack Application (consommatrice)
AWSTemplateFormatVersion: '2010-09-09'
Description: Stack application utilisant la stack réseau
Parameters:
NetworkStackName:
Type: String
Default: network-stack
Description: Nom de la stack réseau
InstanceType:
Type: String
Default: t3.micro
Resources:
ALBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: ALB Security Group
VpcId: !ImportValue
!Sub '${NetworkStackName}-VPCId'
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
AppSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Application Security Group
VpcId: !ImportValue
!Sub '${NetworkStackName}-VPCId'
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 8080
ToPort: 8080
SourceSecurityGroupId: !Ref ALBSecurityGroup
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Sub '${AWS::StackName}-alb'
Subnets: !Split
- ','
- !ImportValue
!Sub '${NetworkStackName}-PublicSubnets'
SecurityGroups:
- !Ref ALBSecurityGroup
Type: application
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub '${AWS::StackName}-tg'
Port: 8080
Protocol: HTTP
VpcId: !ImportValue
!Sub '${NetworkStackName}-VPCId'
HealthCheckPath: /health
TargetType: instance
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
VPCZoneIdentifier: !Split
- ','
- !ImportValue
!Sub '${NetworkStackName}-PrivateSubnets'
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
MinSize: 2
MaxSize: 10
TargetGroupARNs:
- !Ref TargetGroup
LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateData:
InstanceType: !Ref InstanceType
ImageId: !Sub '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
SecurityGroupIds:
- !Ref AppSecurityGroup
Outputs:
ALBEndpoint:
Description: URL de l'application
Value: !Sub 'http://${ApplicationLoadBalancer.DNSName}'
Lister les exports
# Lister tous les exports
aws cloudformation list-exports
# Résultat
{
"Exports": [
{
"ExportingStackId": "arn:aws:cloudformation:...",
"Name": "network-stack-VPCId",
"Value": "vpc-12345678"
},
{
"ExportingStackId": "arn:aws:cloudformation:...",
"Name": "network-stack-PublicSubnets",
"Value": "subnet-1234,subnet-5678"
}
]
}
# Lister les imports d'un export
aws cloudformation list-imports \
--export-name network-stack-VPCId
Contraintes des exports
Règles importantes
- Nom unique : Les noms d'export doivent être uniques dans une région/compte
- Pas de suppression : Impossible de supprimer une stack si ses exports sont utilisés
- Pas de modification : Impossible de modifier un export utilisé
- Même région : Les imports ne fonctionnent que dans la même région
Gérer les dépendances
# Vérifier qui utilise un export
aws cloudformation list-imports --export-name network-stack-VPCId
# Résultat
{
"Imports": [
"arn:aws:cloudformation:...:stack/app-stack-1/...",
"arn:aws:cloudformation:...:stack/app-stack-2/..."
]
}
Erreur typique
Export network-stack-VPCId cannot be deleted as it is in use by app-stack
Solution : Supprimer d'abord les stacks qui importent, puis la stack qui exporte.
Bonnes pratiques
1. Convention de nommage
# ✅ Bon - Préfixe avec le nom de la stack
Export:
Name: !Sub '${AWS::StackName}-VPCId'
# ✅ Bon - Inclure l'environnement
Export:
Name: !Sub '${Environment}-network-VPCId'
# ❌ Mauvais - Nom générique
Export:
Name: VPCId
2. Documenter les exports
Outputs:
VPCId:
Description: |
ID du VPC principal.
Utilisé par: app-stack, database-stack
Format: vpc-xxxxxxxxx
Value: !Ref VPC
Export:
Name: !Sub '${AWS::StackName}-VPCId'
3. Utiliser des paramètres pour les noms de stack
Parameters:
NetworkStackName:
Type: String
Description: Nom de la stack réseau à référencer
Resources:
MyResource:
Properties:
VpcId: !ImportValue
!Sub '${NetworkStackName}-VPCId'
Résumé
| Concept | Description |
|---|---|
| Output | Expose une valeur de la stack |
| Export | Rend un output disponible pour d'autres stacks |
| ImportValue | Importe un export d'une autre stack |
| Condition | Rend un output conditionnel |