Coder Social home page Coder Social logo

maniacs-oss / tf2pulumi Goto Github PK

View Code? Open in Web Editor NEW

This project forked from pulumi/tf2pulumi

0.0 0.0 0.0 919 KB

A tool to convert Terraform projects to Pulumi TypeScript programs

Home Page: https://www.pulumi.com

License: Apache License 2.0

Go 94.09% Makefile 1.03% Shell 0.24% HCL 3.56% Python 0.07% TypeScript 1.01%

tf2pulumi's Introduction

tf2pulumi

Build Status

Convert Terraform projects to Pulumi TypeScript programs.

Goals

The goal of tf2pulumi is to help users efficiently convert Terraform-managed infrastructure into Pulumi stacks. It translates HCL configuration into Pulumi TypeScript programs. In the fullness of time, it will also translate Terraform state files into Pulumi checkpoint files.

Building and Installation

If you wish to use tf2pulumi without developing the tool itself, you can use one of the binary releases hosted on GitHub.

tf2pulumi uses Go modules to manage dependencies. If you want to develop tf2pulumi2 itself, you'll need to have Go installed in order to build. Once this prerequisite is installed, run the following to build the tf2pulumi binary and install it into $GOPATH/bin:

$ go build -o $GOPATH/bin/tf2pulumi main.go

Go should automatically handle pulling the dependencies for you.

If $GOPATH/bin is not on your path, you may want to move the tf2pulumi binary from $GOPATH/bin into a directory that is on your path.

Usage

In order to use tf2pulumi to convert a Terraform project to Pulumi TypeScript and then deploy it, you'll first need to install the Pulumi CLI. Once the Pulumi CLI has been installed, navigate to the same directory as the Terraform project you'd like to import and create a new Pulumi TypeScript stack:

$ pulumi new typescript -f

Then run tf2pulumi which will write a file named index.ts in the directory that contains the Pulumi project you just created:

$ tf2pulumi

If tf2pulumi complains about missing Terraform resource plugins, install those plugins as per the instructions in the error message and re-run the command above.

This will generate a Pulumi TypeScript program in index.ts that when run with pulumi update will deploy the infrastructure originally described by the Terraform project. Note that if your infrastructure references files or directories with paths relative to the location of the Terraform project, you will most likely need to update these paths such that they are relative to the generated index.ts file.

If you would like to adopt resources from an existing .tfstate file under management of a Pulumi stack, copy the import.ts file from this repo into your project folder, and add the following in your generated index.ts file before any resource creations:

...
import "./import";
...

Then set the importFromStatefile config setting on your project to a valid location of a .tfstate file to import resources from that state.

pulumi config set importFromStatefile ./terraform.tfstate

After doing this, the first pulumi up for a new stack with this configuration variable set will import instead of create all of the resources defined in the code. Once imported, the existing resources in your cloud provider can now be managed by Pulumi going forward. See the Adopting Existing Cloud Resources into Pulumi blog post for more details on importing existing resources.

Limitations

While the majority of Terraform constructs are already supported, there are some gaps. Most noteworthy is that tf2pulumi cannot currently convert provisioner blocks. Besides that, the following constructs are not yet implemented:

  • Various built-in interpolation functions. Calls to unimplemented functions will throw at runtime (#12).
  • Multiple provider instances and named providers. If a resource or data source names a provider, the reference is currently ignored (#11).
  • Provisioners. Provisioner blocks are currently ignored (#10).
  • Explicit dependencies in data sources (#1).
  • self and terraform variable references (#2).

Example

The AWS EIP test provides a good example of the results of the conversion on a relatively simple infrastructure definition.

Terraform

The Terraform project is structured like so:

variables.tf
variable "aws_region" {
  description = "The AWS region to create things in."
  default     = "us-east-1"
}

# Amazon Linux 2018.03
variable "aws_amis" {
  default = {
    "us-east-1" = "ami-0ff8a91507f77f867"
    "us-west-2" = "ami-a0cfeed8"
  }
}
main.tf
# Specify the provider and access details
provider "aws" {
  region = "${var.aws_region}"
}

resource "aws_eip" "default" {
  instance = "${aws_instance.web.id}"
  vpc      = true
}

# Our default security group to access
# the instances over SSH and HTTP
resource "aws_security_group" "default" {
  name        = "eip_example"
  description = "Used in the terraform"

  # SSH access from anywhere
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  # HTTP access from anywhere
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  # outbound internet access
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "web" {
  instance_type = "t2.micro"

  # Lookup the correct AMI based on the region
  # we specified
  ami = "${lookup(var.aws_amis, var.aws_region)}"

  # Our Security group to allow HTTP and SSH access
  security_groups = ["${aws_security_group.default.name}"]

  # We run a remote provisioner on the instance after creating it.
  # In this case, we just install nginx and start it. By default,
  # this should be on port 80
  user_data = "${file("userdata.sh")}"

  #Instance tags
  tags {
    Name = "eip-example"
  }
}
outputs.tf
output "address" {
  value = "${aws_instance.web.private_ip}"
}

output "elastic ip" {
  value = "${aws_eip.default.public_ip}"
}

Pulumi

Running tf2pulumi on this project produces the following index.ts file:

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as fs from "fs";

const config = new pulumi.Config();
const awsRegion = config.get("awsRegion") || "us-east-1";
// Amazon Linux 2018.03
const awsAmis = config.get("awsAmis") || {
    "us-east-1": "ami-0ff8a91507f77f867",
    "us-west-2": "ami-a0cfeed8",
};

// Our default security group to access
// the instances over SSH and HTTP
const defaultSecurityGroup = new aws.ec2.SecurityGroup("default", {
    description: "Used in the terraform",
    // outbound internet access
    egress: [{
        cidrBlocks: ["0.0.0.0/0"],
        fromPort: 0,
        protocol: "-1",
        toPort: 0,
    }],
    ingress: [
        // SSH access from anywhere
        {
            cidrBlocks: ["0.0.0.0/0"],
            fromPort: 22,
            protocol: "tcp",
            toPort: 22,
        },
        // HTTP access from anywhere
        {
            cidrBlocks: ["0.0.0.0/0"],
            fromPort: 80,
            protocol: "tcp",
            toPort: 80,
        },
    ],
    name: "eip_example",
});
const web = new aws.ec2.Instance("web", {
    // Lookup the correct AMI based on the region
    // we specified
    ami: (<any>awsAmis)[awsRegion],
    instanceType: "t2.micro",
    // Our Security group to allow HTTP and SSH access
    securityGroups: [defaultSecurityGroup.name],
    //Instance tags
    tags: {
        Name: "eip-example",
    },
    // We run a remote provisioner on the instance after creating it.
    // In this case, we just install nginx and start it. By default,
    // this should be on port 80
    userData: fs.readFileSync("userdata.sh", "utf-8"),
});
const defaultEip = new aws.ec2.Eip("default", {
    instance: web.id,
    vpc: true,
});

export const address = web.privateIp;
export const elastic_ip = defaultEip.publicIp;

The Terraform variables have been converted to Pulumi config values, the resources to calls to the appropriate Pulumi resource constructors, and the outputs to export statements.

tf2pulumi's People

Contributors

pgavlin avatar jaxxstorm avatar joeduffy avatar cyrusnajmabadi avatar lukehoban avatar jen20 avatar stack72 avatar swgillespie avatar ellismg avatar ericrudder avatar mikhailshilkov avatar hobbsh avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.