我有一个CloudFormation模板,可以在同一堆栈下创建RDS和EC2。我的问题是,如何在不安装AWS cli和添加凭据的情况下将RDS主机名放入EC2内部的环境变量之一中?
答案 0 :(得分:1)
这个想法与[tyron]中的想法相同,但是实际上您可以使代码在YAML中更短,因为!Sub可以将!GetAtt解析为一个表达式:
Resources:
Rds:
Type: AWS::RDS::DBInstance
Properties:
...
Ec2:
Type: AWS::EC2::Instance
Properties:
...
UserData:
Fn::Base64:
!Sub |
#!/bin/bash
echo "DB_CONNECTION=${Rds.Endpoint.Address}" >> /etc/profile
$ {Rds.Endpoint.Address}将由!Sub解析-在启动实例之前-即使语法看起来非常相似,我们也不会由bash shell对其进行解释。
UserData中的实际shell代码取决于打算使用该变量的人员(哪个用户/进程)。使用我给出的代码,应在系统范围内进行设置,因此无论谁登录,都应具有该属性。当然,如果该进程已经在运行并且已经读取了env属性,它将看不到新值-只有在执行用户数据后才启动新的Shell实例。
针对所需的shell代码的最佳检查相关答案,例如:https://stackoverflow.com/a/1641531/4966203
答案 1 :(得分:0)
我假设“ RDS主机名”是您的RDS端点?
您可以将您的EC2用户数据添加到下面的代码中。我不太习惯linux,所以不确定这是否是设置环境变量的方法,但是您明白了。
Resources:
Rds:
Type: 'AWS::RDS::DBInstance'
Properties:
...
Ec2:
Type: 'AWS::EC2::Instance'
Properties:
...
UserData: !Base64
'Fn::Sub':
- |-
<script>
export DB_CONNECTION="${RdsEndpoint}"
</script>
- { RdsEndpoint: !GetAtt Rds.Endpoint.Address }
更新
在这种特殊情况下,由于引用需要使用Fn::Sub
,因此您需要使用Fn::GetAtt
的长语法。如果您想要的信息是通过简单的Fn::Ref
检索的,则可以使用以下简短语法:
UserData: !Base64
'Fn::Sub':
<script>
export DB_CONNECTION="${Rds}" # <-- this will get the DBInstanceIdentifier
</script>
更新2 :正如Josef指出的那样,无论源是!Ref还是!GetAtt,您仍然可以使用短语法。所以这是有效的:
UserData: !Base64
'Fn::Sub': |-
<script>
export DB_CONNECTION="${Rds.Endpoint.Address}"
</script>