如何将 RDS 实例的主机名放入 EC2 的环境变量中?
How do I get the hostname of RDS instance into an Environment variable in EC2?
我有一个 CloudFormation 模板,可以在同一个堆栈下创建 RDS 和 EC2。我的问题是,如何将 RDS 主机名放入我的 EC2 中的环境变量之一,而无需安装 AWS cli 和添加凭据?
我假设 "RDS hostname" 是您的 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>
想法与 [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 代码的最佳检查相关答案,例如:
我有一个 CloudFormation 模板,可以在同一个堆栈下创建 RDS 和 EC2。我的问题是,如何将 RDS 主机名放入我的 EC2 中的环境变量之一,而无需安装 AWS cli 和添加凭据?
我假设 "RDS hostname" 是您的 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>
想法与 [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 代码的最佳检查相关答案,例如: