Coder Social home page Coder Social logo

cdktf / projen-cdktf-hybrid-construct Goto Github PK

View Code? Open in Web Editor NEW
10.0 2.0 4.0 2.24 MB

Projen template for CDKTF Constructs that should also be used as Terraform Modules.

License: Mozilla Public License 2.0

TypeScript 96.31% HCL 1.29% Shell 2.40%
constructs cdk cdktf terraform-cdk terraform-modules projen

projen-cdktf-hybrid-construct's Introduction

Projen-CDKTF-Hybrid-Construct

Status: Tech Preview Releases LICENSE build

Projen template for CDKTF Constructs that should also be used as Terraform Modules and for republishing Terraform Modules as Constructs.

projen-cdktf-hybrid-construct is in technical preview, which means it's a community supported project. It still requires extensive testing and polishing to mature into a HashiCorp officially supported project. Please file issues generously and detail your experience while using the library. We welcome your feedback.

By using the software in this repository, you acknowledge that:

  • projen-cdktf-hybrid-construct is still in development, may change, and has not been released as a commercial product by HashiCorp and is not currently supported in any way by HashiCorp.
  • projen-cdktf-hybrid-construct is provided on an "as-is" basis, and may include bugs, errors, or other issues.
  • projen-cdktf-hybrid-construct is NOT INTENDED FOR PRODUCTION USE, use of the Software may result in unexpected results, loss of data, or other unexpected results, and HashiCorp disclaims any and all liability resulting from use of projen-cdktf-hybrid-construct.
  • HashiCorp reserves all rights to make all decisions about the features, functionality and commercial release (or non-release) of projen-cdktf-hybrid-construct, at any time and without any obligation or liability whatsoever.

Compatibility

  • cdktf >= 0.20.0
  • constructs >= 10.3.0

Usage

HybridModule

If you want to write a CDKTF construct and also publish it as a Terraform Module you can use the HybridModule template.

You can initialize such a project using npx projen new --from projen-cdktf-hybrid-construct hybrid-module.

A configuration might look like this:

const { HybridModule } = require("projen-cdktf-hybrid-construct");

const project = new HybridModule({
  // The name of the module & repository need to start with terraform-cdk-
  name: "terraform-cdk-my-new-hybrid-construct",
  repositoryUrl:
    "github.com/DanielMSchmidt/terraform-cdk-my-new-hybrid-construct",

  author: "Daniel Schmidt",
  authorAddress: "[email protected]",

  // If enabled an example folder with terraform code will be created
  terraformExamples: {
    enabled: true,
    folder: "terraform",
    // The configuration to add to the example terraform file
    providerConfig: `
        terraform {
          required_providers {
            aws = {
              source  = "hashicorp/aws"
              version = "~> 3.74"
            }
          }
          # Terraform binary version constraint
          required_version = ">= 1.2.0"
        }
        
        
        provider "aws" {
          region = "eu-central-1"
        }
        `,
  },

  // If enabled a constructs example folder will be created
  constructExamples: {
    enabled: true,
    folder: "construct-examples",
  },
});
project.synth();

TerraformModule

If you want to republish an existing Terraform module as a CDKTF construct or if you want to repackage them with an easier to use API you can use the TerraformModule template.

You can initialize such a project using npx projen new --from projen-cdktf-hybrid-construct terraform-module.

A configutation might look like this:

const { TerraformModule } = require("projen-cdktf-hybrid-construct");

const project = new TerraformModule({
  name: "my-module",
  author: "Daniel Schmidt",
  authorAddress: "[email protected]",
  repositoryUrl: "github.com/DanielMSchmidt/my-module",

  terraformModules: [
    {
      name: "eks",
      source: "terraform-aws-modules/eks/aws",
      version: "~> 18.0",
    },
    {
      name: "eks-managed-nodegroup",
      source: "terraform-aws-modules/eks/aws//modules/eks-managed-node-group",
      version: "~> 18.0",
    },
  ],
});

project.synth();

Publishing

Open Source

We have a helper method for easy configuration, but there are still some manual steps required.

const {
  HybridModule,
  publishToRegistries,
} = require("projen-cdktf-hybrid-construct");

const project = new HybridModule({
  // ... all the other options
  ...publishToRegistries({
    name: "my-new-hybrid-construct",
    namespace: "my-org",
    registries: ["npm", "pypi", "nuget", "maven"],
  }),
});

Terraform

  1. Sign in at the registry
  2. Select your repository and create the module

Please make sure your repository name starts with terraform-cdk-.

npm (Typescript)

  1. Create an account at npmjs.com
  2. Create an automation token on npm
  3. Create a GitHub Action Secret with the name NPM_TOKEN and the value of the token

pypi (Python)

  1. Create an account at pypi.org
  2. Create an API token on pypi
  3. Create a GitHub Action Secret with the name TWINE_USERNAME and the value __token__ and a second one with the name TWINE_PASSWORD and the value of the token
  4. Set the publishToPypi section in the options of HybridModule or TerraformModule (or use the helper mentioned above)
const name = "name-of-my-hybrid-construct";
new HybridModule({
  name,
  // ... other options
  publishToPypi: {
    distName: name,
    module: name.replace(/-/g, "_"),
  },
});

Maven (Java)

  1. Create a Sonatype account and repository
  2. Create GitHub Action Secrets to configure maven:
    • MAVEN_USERNAME
    • MAVEN_PASSWORD
    • MAVEN_STAGING_PROFILE_ID
    • MAVEN_GPG_PRIVATE_KEY_PASSPHRASE
    • MAVEN_GPG_PRIVATE_KEY_PASSPHRASE
  3. Setup the publishToMaven section in the options of HybridModule or TerraformModule (or use the helper mentioned above)
const githubNamespace = "my-org";
const name = "name-of-my-hybrid-construct";
new HybridModule({
  name,
  // ... other options
  publishToMaven: {
    javaPackage: name.replace(/-/g, "_"),
    mavenGroupId: `com.${githubNamespace}`,
    mavenArtifactId: name,
  },
});

NuGet (C#)

  1. Create a NuGet account (you might need to create a Microsoft Account if you don't have one)
  2. Create API keys
  3. Create a GitHub Action Secret with the name NUGET_API_KEY and the value of the token
  4. Setup the publishToNuget section in the options of HybridModule or TerraformModule (or use the helper mentioned above)
const githubNamespace = "my-org";
const name = "name-of-my-hybrid-construct";

new HybridModule({
  name,
  // ... other options
  publishToNuget: {
    dotNetNamespace: `MyOrg.NameOfMyHybridConstruct`,
    packageId: `MyOrg.NameOfMyHybridConstruct`,
  },
});

Github Packages

We have a helper method for easy configuration, no extra steps needed:

const {
  HybridModule,
  publishToGithubPackages,
} = require("projen-cdktf-hybrid-construct");

const project = new HybridModule({
  // ... all the other options
  ...publishToGithubPackages({
    name: "my-new-hybrid-construct",
    namespace: "my-org",
    registries: ["npm", "maven"], // pypi and nuget are not yet supported
  }),
});

Artifactory

We have a helper method for easy configuration, but there are also some manual steps required.

const {
  HybridModule,
  publishToGithubPackages,
} = require("projen-cdktf-hybrid-construct");

const project = new HybridModule({
  // ... all the other options
  ...publishToGithubPackages({
    name: "my-new-hybrid-construct",
    namespace: "my-org",
    registries: ["npm", "pypi", "nuget"], // maven is currently not supported, PRs welcome
    artifactoryApiUrl: "https://artifactory.my-org.com/api/",
    artifactoryRepository: "my-repo", // needs to be the same across all registries, defaults to namespace so "my-org" in this case
  }),
});

Terraform

You can find more information about publishing Terraform Modules to Artifactory here.

npm (Typescript)

  1. Create a virtual npm registry
  2. Authenticate against artifactory to get a token
  3. Create a GitHub Action Secret with the name NPM_TOKEN and the value of the token

pypi (Python)

  1. Create a local repository
  2. Create a GitHub Action Secret with the name TWINE_USERNAME and the artifactory user name and a second one with the name TWINE_PASSWORD and the artifactory password

projen-cdktf-hybrid-construct's People

Contributors

bollohz avatar danielmschmidt avatar dependabot[bot] avatar froblesmartin avatar team-tf-cdk avatar xiehan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

projen-cdktf-hybrid-construct's Issues

TFModuleStack created inside src sub folders are not getting synthesized on running build command

Description

I have created a TFModule stack under directory "src/services/azure/static-app" as follows:

import {
  ProviderRequirement,
  TFModuleStack,
  TFModuleVariable,
} from "@cdktf/tf-module-stack";
import { App } from "cdktf";
import { Construct } from "constructs";
import { AzStaticApp } from "./main";

class AzStaticAppModule extends TFModuleStack {
  constructor(scope: Construct, id: string) {
    super(scope, id);
    let azurermProvider = new ProviderRequirement(this, "azurerm", "~> 3.70.0", "hashicorp/azurerm");  

    new ProviderRequirement(this, "github", "~> 5.36.0", "integrations/github");

    let appName = new TFModuleVariable(this, "appName", {
      type: "string",
      description: "Name of the application",
      default: "test-app",
    });
    let environmentName = new TFModuleVariable(this, "environmentName", {
      type: "string",
      default: "dev",
    });
    let location = new TFModuleVariable(this, "location", {
      type: "string",
      default: "westeurope",
    });
    let skuSize = new TFModuleVariable(this, "skuSize", {
      type: "string"      
    });
    let skuTier = new TFModuleVariable(this, "skuTier", {
      type: "string"      
    });   
    
    let namePrefix = new TFModuleVariable(this, "namePrefix", {
      type: "string",
      description: "Prefix for all resources",
      default: "tf",
    }); 
    
    let apiLocation = new TFModuleVariable(this, "apiLocation", {
      type: "string", 
      default: "api"     
    });

    let appLocation = new TFModuleVariable(this, "appLocation", {
      type: "string"      
    });

    let appBuildCommand = new TFModuleVariable(this, "appBuildCommand", {
      type: "string"      
    });

    let repositoryName = new TFModuleVariable(this, "repositoryName", {
      type: "string"      
    });

    let branchName = new TFModuleVariable(this, "branchName", {
      type: "string"      
    });

    let apiTokenVar = new TFModuleVariable(this, "apiTokenVar", {
      type: "string"      
    });

    let outputLocation = new TFModuleVariable(this, "outputLocation", {
      type: "string"      
    });

    let existingRgName = new TFModuleVariable(this, "existingRgName", {
      type: "string",
      default: ""    
    });

    let providerAlias = new TFModuleVariable(this, "providerAlias", {
      type: "string",
      default: ""    
    });

    let tags = new TFModuleVariable(this, "tags", {
      type: "map(string)"      
    });

    azurermProvider.alias = providerAlias.value;
    new AzStaticApp(this, "static-app", {
      provider: azurermProvider,
      appName: appName.value,
      environmentName: environmentName.value,
      location: location.value,
      skuSize: skuSize.value,
      skuTier: skuTier.value,          
      namePrefix: namePrefix.value,
      apiLocation: apiLocation.value,
      appLocation: appLocation.value,
      appBuildCommand: appBuildCommand.value,
      repositoryName: repositoryName.value, 
      branchName: branchName.value,
      apiTokenVar: apiTokenVar.value,
      outputLocation: outputLocation.value,
      tags: tags.value,
      existingRgName: existingRgName.value           
    });
  }
}

const app = new App();
// This is the name the module can be found under.
// We expect a "my-awesome-module.md" file in this directory.
// The README.md file will be generated from this file.
new AzStaticAppModule(app, "az-static-app");
app.synth();

Directory Structure:
image

Versions

language: null
cdktf-cli: 0.18.0
node: v18.17.1
terraform: 1.5.2
arch: x64
os: win32 10.0.19045

Providers

No response

Gist

No response

Possible Solutions

No response

Workarounds

No response

Anything Else?

No response

References

No response

Help Wanted

  • I'm interested in contributing a fix myself

Community Note

  • Please vote on this issue by adding a ๐Ÿ‘ reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Use of `cdktf-tf-module-stack` instead of `@cdktf/tf-module-stack`

Description

After hitting some errors, one causing issue I believe is the use of cdktf-tf-module-stack instead of @cdktf/tf-module-stack in this project.
The now old (seemingly not maintained) cdktf-tf-module-stack package gets installed into node-modules and appears in dependencies after a fresh npx projen new --from projen-cdktf-hybrid-construct hybrid-module and causes package dependency issues. This is most probably because its use in https://github.com/cdktf/projen-cdktf-hybrid-construct/blob/main/src/hybrid-module.ts.

I believe this needs to be replaced with @cdktf/tf-module-stack.

Versions

language: null
cdktf-cli: 0.17.3
node: v18.16.1
terraform: 1.5.4
arch: arm64
os: darwin 22.5.0

Providers

No response

Gist

No response

Possible Solutions

No response

Workarounds

No response

Anything Else?

No response

References

No response

Help Wanted

  • I'm interested in contributing a fix myself

Community Note

  • Please vote on this issue by adding a ๐Ÿ‘ reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

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.