如何使用 Cloudformation 模板中的变量作为 terraform 中 "Data source" 的特征

How to work with variables in Cloudformation template as the feature of "Data source" in terraform

在terraform中,我们可以使用data source获取存在的资源详情。

但是在 cloudformation 中,如果资源不是由 cloudformation 模板创建的,我找不到任何方法来引用它,除非我对值进行硬编码,例如真实的 vpc id。

有什么建议吗?

您可以这样做的一种方法是使用参数(例如 AWS::EC2::VPC::Id 表示 vpc ID)。在创建堆栈时,这将列出您在其中创建堆栈的区域中的所有现有 vpc。目前,此类参数仅限于少数几个,例如卷、子网、sg,但将来可能会出现更多。尽管目前在 cloudformation 中还没有任何与 terraform 数据源完全相同的东西。您也可以使用 cloudformation 宏来设计一些东西,但这会有点令人费解。

最后我用cloudformation做了一个vpc栈,它从aws cli获取参数输入并输出vpc id,subnet id等

此cloudformation模板只有一个空资源(因为cloudformation模板中没有资源会报错)

Description: >
  This template deploys a VPC, with a pair of public and private subnets spread
  across two Availabilty Zones. It deploys an Internet Gateway, with a default
  route on the public subnets. It deploys a pair of NAT Gateways (one in each AZ),
  and default routes for them in the private subnets.
Parameters:

  EnvironmentName:
    Description: An environment name that will be prefixed to resource names
    Type: String

  VPC:
    Description: Please enter the VPC ID
    Type: String

  VpcCIDR:
    Description: Please enter the IP range (CIDR notation) for this VPC
    Type: String

  PublicSubnet1:
    Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone
    Type: String

  PublicSubnet2:
    Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone
    Type: String

  PrivateSubnet1:
    Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone
    Type: String

  PrivateSubnet2:
    Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone
    Type: String

Conditions:
  HasNot: !Equals [ 'true', 'false' ]

Resources:
  NullResource:
    Type: 'Custom::NullResource'
    Condition: HasNot

Outputs:

  VPC:
    Description: A reference to the created VPC
    Value: !Ref VPC
    Export:
      Name: !Sub "${EnvironmentName}:VPC"

  PublicSubnet1:
    Description: A reference to the public subnet in the 1st Availability Zone
    Value: !Ref PublicSubnet1
    Export:
      Name: !Sub "${EnvironmentName}:PublicSubnet1"

  PublicSubnet2:
    Description: A reference to the public subnet in the 2nd Availability Zone
    Value: !Ref PublicSubnet2
    Export:
      Name: !Sub "${EnvironmentName}:PublicSubnet2"

  PrivateSubnet1:
    Description: A reference to the private subnet in the 1st Availability Zone
    Value: !Ref PrivateSubnet1
    Export:
      Name: !Sub "${EnvironmentName}:PrivateSubnet1"

  PrivateSubnet2:
    Description: A reference to the private subnet in the 2nd Availability Zone
    Value: !Ref PrivateSubnet2
    Export:
      Name: !Sub "${EnvironmentName}:PrivateSubnet2"

  VpcCIDR:
    Description: VPC CIDR
    Value: !Ref VpcCIDR
    Export:
      Name: !Sub "${EnvironmentName}:VpcCIDR"

我运行一个bash脚本来收集这些数据(你可以写javascript,pytyon或任何其他语言来收集这些数据),将它们作为参数提供给上面的cloudformation .

#!/bin/bash

set -ex

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

# collect the vpc details.
# you can run aws cli or any aws sdk to collect them.
source ../common_function.sh
echo ${VPC_ID}

aws --profile "${AWS_PROFILE}" --region "${AWS_DEFAULT_REGION}" \
    cloudformation deploy \
    --stack-name "${ENVIRONMENT_NAME}-vpc" \
    --capabilities CAPABILITY_IAM \
    --template-file "${DIR}/vpc.yaml" \
    --parameter-overrides \
    EnvironmentName="${ENVIRONMENT_NAME}" \
    VPC="${VPC_ID}" \
    VpcCIDR="${VPC_CIDR}" \
    PublicSubnet1="${PUBLIC_SUBNET_ID_1}" \
    PublicSubnet2="${PUBLIC_SUBNET_ID_2}" \
    PrivateSubnet1="${PRIVATE_SUBNET_ID_1}" \
    PrivateSubnet2="${PRIVATE_SUBNET_ID_2}"

在 cfn 堆栈之上部署后,您可以在其他 cfn 堆栈中引用这些输出变量。

VpcId:
    'Fn::ImportValue': !Sub "${EnvironmentName}:VPC"