# Cloudformation to terraform conversion

**URL:** <https://discuss.hashicorp.com/t/cloudformation-to-terraform-conversion/23766>\
**Category:** AWS\
**Created:** [April 28, 2021, 10:55am UTC](https://discuss.hashicorp.com/t/cloudformation-to-terraform-conversion/23766 "2021-04-28T10:55:32Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tyroform](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/tyroform/32/16286_2.png) [@Tyroform](https://discuss.hashicorp.com/u/Tyroform)\
**Post date:** [April 28, 2021, 10:55am UTC](https://discuss.hashicorp.com/t/cloudformation-to-terraform-conversion/23766/1 "2021-04-28T10:55:32Z")

</div>

Hi,

I have the following piece of code to be converted from cloudformation to terraform:

**Cloudformation**

```
   lbdServicesBInfoDurationAlarm:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      AlarmName: lbdServicesBInfoDurationAlarm
      AlarmDescription: Alarm if elapsed wall clock time is too high
      AlarmActions:
        - !ImportValue 
          'Fn::Sub': '${EnvName}CWNotificationTopicARN'
      Dimensions:
        - Name: FunctionName
          Value: !Sub '${lbdServicesBInfoFunctionName}-${EnvName}'**
      Namespace: AWS/Lambda
      MetricName: Duration
      ComparisonOperator: GreaterThanThreshold
      EvaluationPeriods: '1'
      Period: '300'
      Statistic: Sum
      Threshold: '30000'
      TreatMissingData: missing

```

**Terraform:**

```
resource "aws_cloudwatch_metric_alarm" "lbdServicesBInfoDurationAlarm" {
  alarm_name = "lbdServicesBInfoDurationAlarm"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods = "1"
  metric_name = "Duration"
  namespace = "AWS/Lambda"
  period = "300"
  statistic = "Sum"
  threshold = "30000"
  alarm_description = "Alarm if elapsed wall clock time is too high"
  treat_missing_data = "missing"
  insufficient_data_actions = []
}

```

I am not sure how to convert AlarmActions and Dimensions from CF to TF. Any help will be appreciated.

---

<div class="post-metadata">

**Author:** ![apparentlymart](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/apparentlymart/32/702_2.png) [@apparentlymart](https://discuss.hashicorp.com/u/apparentlymart)\
**Post date:** [April 28, 2021, 5:24pm UTC](https://discuss.hashicorp.com/t/cloudformation-to-terraform-conversion/23766/2 "2021-04-28T17:24:14Z")

</div>

Hi @Tyroform,

I think the closest equivalent to `!ImportValue` in Terraform would be to use a [data source](https://www.terraform.io/docs/language/data-sources/index.html) to read the data you need. If you are doing a gradual migration where this notification topic ARN will remain in CloudFormation for now then you can directly translate `!ImportValue` into a use of [the `aws_cloudformation_export` data source](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudformation_export), which knows how to read an exported value from CloudFormation in the same way that `!ImportValue` does:

```auto
variable "environment_name" {
  type = string
}

data "aws_cloudformation_export" "topic_arn" {
  name = "${var.environment_name}CWNotificationTopicARN"
}

resource "aws_cloudwatch_metric_alarm" "lbdServicesBInfoDurationAlarm" {
  alarm_name = "lbdServicesBInfoDurationAlarm"
  alarm_actions = [data.aws_cloudformation_export.topic_arn.value]
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods = "1"
  metric_name = "Duration"
  namespace = "AWS/Lambda"
  period = "300"
  statistic = "Sum"
  threshold = "30000"
  alarm_description = "Alarm if elapsed wall clock time is too high"
  treat_missing_data = "missing"
  insufficient_data_actions = []
}

```

For `Fn::Sub` you don’t really need to do anything particularly special in Terraform, because Terraform interprets all quoted strings as templates supporting interpolation by default. You can see one example of that above in the `name` argument in `data "aws_cloudformation_export" "topic_arn"`. A similar principle would apply to your dimensions value, using `${var.environment_name}` just as I did above along with some other referenc equivalent to `lbdServicesBInfoFunctionName` (but I don’t know what that is in order to make a specific suggestion.)

* * *

Another note I would add, since we’re talking about converting from CloudFormation to Terraform anyway, is the more subjective concern of naming conventions. The names you’ve translated directly from CloudFormation are syntactically valid in Terraform, but don’t suit the typical Terraform style conventions. In particular:

- Names within Terraform conventionally use lowercase letters with underscores separating words, like `lbd_services_b_info_duration_alarm` rather than `lbdServicesBInfoDurationAlarm`.

- Because we always refer to a resource by stating both its type and its name, the name portion typically shouldn’t duplicate nouns from the type.

Terraform itself (the software) doesn’t enforce either of these, but following these conventions will make your configuration feel more familiar to folks who already have some Terraform experience.

---

<div class="post-metadata">

**Author:** ![Tyroform](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/tyroform/32/16286_2.png) [@Tyroform](https://discuss.hashicorp.com/u/Tyroform)\
**Post date:** [April 30, 2021, 7:21pm UTC](https://discuss.hashicorp.com/t/cloudformation-to-terraform-conversion/23766/3 "2021-04-30T19:21:36Z")

</div>

Thank you for your valuable feedback @apparentlymart!!!

---

<div class="post-metadata">

**Author:** ![shadycuz](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/shadycuz/32/3994_2.png) [@shadycuz](https://discuss.hashicorp.com/u/shadycuz)\
**Post date:** [June 17, 2022, 7:20pm UTC](https://discuss.hashicorp.com/t/cloudformation-to-terraform-conversion/23766/4 "2022-06-17T19:20:57Z")

</div>

Today I released a tool that does _most_ of the work for you [GitHub - DontShaveTheYak/cf2tf: Convert Cloudformation templates to Terraform.](https://github.com/DontShaveTheYak/cf2tf)

---

<div class="post-metadata">

**Author:** ![t-sivasakthi](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/t-sivasakthi/32/37039_2.png) [@t-sivasakthi](https://discuss.hashicorp.com/u/t-sivasakthi)\
**Post date:** [July 26, 2023, 2:19pm UTC](https://discuss.hashicorp.com/t/cloudformation-to-terraform-conversion/23766/5 "2023-07-26T14:19:09Z")

</div>

@shadycuz I got the following error when I try to convert the cloud formation template to terraform script.

```auto
% cf2tf lambda_cdk_template.yml 
// Converting lambda_cdk_template.yml to Terraform!
 existing repo found.
Traceback (most recent call last):
  File "/opt/homebrew/bin/cf2tf", line 8, in <module>
    sys.exit(cli())
             ^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/cf2tf/app.py", line 44, in cli
    config = TemplateConverter(tmpl_path.stem, cf_template, search_manger).convert()
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/cf2tf/convert.py", line 92, in convert
    tf_resources = self.convert_to_tf(self.manifest)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/cf2tf/convert.py", line 139, in convert_to_tf
    tf_resources.extend(converter(resources))
                        ^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/cf2tf/convert.py", line 297, in convert_resources
    valid_arguments, valid_attributes = doc_file.parse_attributes(docs_path)
                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/cf2tf/terraform/doc_file.py", line 15, in parse_attributes
    attributes = parse_section("Attributes Reference", file)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/cf2tf/terraform/doc_file.py", line 31, in parse_section
    section_location = find_section(name, file)
                       ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/cf2tf/terraform/doc_file.py", line 111, in find_section
    raise Exception()
Exception

```
