Reputation: 513
I’m having issues to obtain some RDS Instance attributes from my EC2 Metadata configSet block using !Sub and !GetAtt functions combined.
So, at the resources key in my serverless.yml file I have (among other things) an EC2 instance (OASInstance) and an RDS instance (OASRDSInstance). I’m trying to build a connection string for my DB hosted on RDS, and for that, I’m using !Sub and !GetAtt functions inside a file definition on the Metadata block at my EC2 instance definition.
I’ve tried this in several ways, using short and long syntax format, but I make sure that this one works on a CloudFormation template:
- Fn::Sub:
- "${RDSEndpointURL}:${RDSEndpointPort}:ORCL"
- {RDSEndpointURL: !GetAtt OASRDSInstance.Endpoint.Address, RDSEndpointPort: !GetAtt OASRDSInstance.Endpoint.Port}
The error I’m getting when I try to deploy this template is this one:
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.
However, the same code block works perfectly if I use it in the same place on a CloudFormation template.
My guess is that serverless is confusing {RDSEndpointURL} and {RDSEndpointPort} with local template variables, and doesn’t realize that those are just for the !Sub context.
The template is pretty big (especially the EC2 Metadata section), so I'm posting here just the relevant part and putting '...' in not relevant sections.
This is the path you should check:
...
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: ...
...
What should I do?
Thanks
Upvotes: 0
Views: 244
Reputation: 513
Well, I found a workaround.
I replace !Sub with !Join.
This is what I had:
- Fn::Sub:
- "${RDSEndpointURL}:${RDSEndpointPort}:ORCL"
- {RDSEndpointURL: !GetAtt OASRDSInstance.Endpoint.Address, RDSEndpointPort: !GetAtt OASRDSInstance.Endpoint.Port}
And this is the replacement:
- !Join
- ''
- - !GetAtt OASRDSInstance.Endpoint.Address
- ':'
- !GetAtt OASRDSInstance.Endpoint.Port
- ':'
- ${self:custom.RDSDbName}
However, I would like to know if there is a better way.
Upvotes: 0