amazon-web-services - 无服务器模板上 EC2 元数据上的 !Sub 和 !GetAtt 问题
问题描述
我在使用!Sub和!GetAtt函数从我的 EC2 元数据 configSet 块中获取一些 RDS 实例属性时遇到问题。
因此,在我的 serverless.yml 文件中的资源键中,我(除其他外)有一个 EC2 实例(OASInstance)和一个 RDS 实例(OASRDSInstance)。我正在尝试为托管在 RDS 上的数据库构建连接字符串,为此,我在 EC2 实例定义的元数据块上的文件定义中使用!Sub和!GetAtt函数。
我已经尝试了多种方法,使用短语法格式和长语法格式,但我确保这个方法适用于 CloudFormation 模板:
- Fn::Sub:
- "${RDSEndpointURL}:${RDSEndpointPort}:ORCL"
- {RDSEndpointURL: !GetAtt OASRDSInstance.Endpoint.Address, RDSEndpointPort: !GetAtt OASRDSInstance.Endpoint.Port}
我尝试部署此模板时遇到的错误是:
Serverless Error ---------------------------------------
Invalid variable reference syntax for variable RDSEndpointURL. You can only reference env vars, options, & files. You can check our docs for more info.
但是,如果我在 CloudFormation 模板的相同位置使用相同的代码块,则它可以完美运行。
我的猜测是,无服务器将 {RDSEndpointURL} 和 {RDSEndpointPort} 与本地模板变量混淆了,并且没有意识到这些只是用于 !Sub 上下文。
模板非常大(尤其是 EC2 元数据部分),所以我在这里只发布相关部分并将“...”放在不相关的部分中。
...
resources:
Resources:
OASRDSInstance:
Type: 'AWS::RDS::DBInstance'
Properties:
AllocatedStorage: 20
BackupRetentionPeriod: 0
CopyTagsToSnapshot: True
DBInstanceClass: db.m5.xlarge
DBInstanceIdentifier: oas-rcu-central
DBName: ORCL
DBParameterGroupName: default.oracle-ee-19
DBSubnetGroupName: default-vpc
Engine: oracle-ee
EngineVersion: 19.0.0.0.ru-2020-07.rur-2020-07.r1
KmsKeyId: arn:aws:kms:us-east-1:1111111111:key/aaaa-bbbb-cccc-eeee-dddd
LicenseModel: bring-your-own-license
MasterUserPassword: ${self:custom.rcuSysDBPassword}
MasterUsername: admin
OptionGroupName: default:oracle-ee-19
Port: 1521
StorageEncrypted : True
StorageType : gp2
OASInstance:
Type: 'AWS::EC2::Instance'
DependsOn: OASRDSInstance
Metadata:
'AWS::CloudFormation::Init':
configSets:
InstallAndRun:
- OsRequirements
- AddSwap
- InstallJDK
- PrepareFolders
- PreOracleInventory
- OracleInventory
- PreInstallWLS
- InstallWLS
- PrePatchWLS
- PatchWLS
- PreInstallOAS
- InstallOAS
- CreateRCU
- ConfigureOAS
- RunOAS
OsRequirements: ...
AddSwap: ...
InstallJDK: ...
PrepareFolders: ...
PreOracleInventory: ...
OracleInventory: ...
PreInstallWLS: ...
InstallWLS: ...
PrePatchWLS: ...
PatchWLS: ...
InstallOAS: ...
CreateRCU:
commands:
cmd00:
command: echo 'Create RCU' >> /tmp/OASsetup.log
cmd01_01:
command: !Join
- ''
- - sudo -u oracle sh -c '(echo "
- !Ref RcuSysDBPassword
- '"; echo "'
- !Ref RcuSchemasDBPassword
- '") > /home/oracle/rcu_password.dat'''
cmd02_01:
command: !Join
- ''
- - 'sudo -u oracle '
- !FindInMap
- TemplateParams
- paths
- OracleHome
- '/oracle_common/bin/rcu '
- '-silent '
- '-createRepository '
- '-schemaPrefix '
- !Ref RcuDBPrefix
- ' '
- '-useSamePasswordForAllSchemaUsers true '
- '-connectString '
- Fn::Sub:
- "${RDSEndpointURL}:${RDSEndpointPort}:ORCL"
- {RDSEndpointURL: !GetAtt OASRDSInstance.Endpoint.Address, RDSEndpointPort: !GetAtt OASRDSInstance.Endpoint.Port}
- ' '
- '-dbUser '
- !Ref RcuSysDBUser
- ' '
- '-databaseType ORACLE '
- '-dbRole Normal '
- '-honorOMF '
- >-
-component STB -component MDS -component WLS -component OPSS
-component BIPLATFORM -component IAU -component IAU_APPEND
-component IAU_VIEWER
- '-f < /home/oracle/rcu_password.dat'
cmd03_01:
command: rm /home/oracle/rcu_password.dat
ConfigureOAS: ...
RunOAS: ...
Properties:
IamInstanceProfile: dev-k12-oas-InstanceRole
ImageId: !FindInMap
- AWSRegionArch2AMI
- !Ref 'AWS::Region'
- !FindInMap
- AWSInstanceType2Arch
- !Ref InstanceType
- Arch
InstanceType: !Ref InstanceType
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: 25
VolumeType: gp2
NetworkInterfaces:
- AssociatePublicIpAddress: false
DeviceIndex: '0'
GroupSet:
- !Ref OASSecurityGroup
SubnetId: subnet-aaaaaaaaaaaaaaaa
KeyName: !Ref KeyName
Tags:
- Key: "Name"
Value: !Ref "AWS::StackName"
UserData: !Base64
'Fn::Join':
- ''
- - |
#!/bin/bash -xe
- |
yum update -y aws-cfn-bootstrap
- |
# Install the files and packages from the metadata
- '/opt/aws/bin/cfn-init -v '
- ' --stack '
- !Ref 'AWS::StackName'
- ' --resource OASInstance '
- ' --configsets InstallAndRun '
- ' --region '
- !Ref 'AWS::Region'
- |+
- |
# Signal the status from cfn-init
- '/opt/aws/bin/cfn-signal -e $? '
- ' --stack '
- !Ref 'AWS::StackName'
- ' --resource OASInstance '
- ' --region '
- !Ref 'AWS::Region'
- |+
CreationPolicy:
ResourceSignal:
Timeout: PT45M
OASSecurityGroup: ...
OASLoadBalancerSG: ...
OASTargetGroup: ...
OASLoadBalancer: ...
OASHttpLoadBalancerListener: ...
OASLoadBalancerListener: ...
PrivateDNSRecord: ...
...
我应该怎么办?
谢谢
解决方案
好吧,我找到了解决方法。
我将!Sub替换为!Join。
这就是我所拥有的:
- Fn::Sub:
- "${RDSEndpointURL}:${RDSEndpointPort}:ORCL"
- {RDSEndpointURL: !GetAtt OASRDSInstance.Endpoint.Address, RDSEndpointPort: !GetAtt OASRDSInstance.Endpoint.Port}
这是替换:
- !Join
- ''
- - !GetAtt OASRDSInstance.Endpoint.Address
- ':'
- !GetAtt OASRDSInstance.Endpoint.Port
- ':'
- ${self:custom.RDSDbName}
但是,我想知道是否有更好的方法。