diff --git a/content/blog/building-and-publishing-docker-images-to-a-private-amazon-ecr-repository/container-def.png b/content/blog/building-and-publishing-docker-images-to-a-private-amazon-ecr-repository/container-def.png new file mode 100644 index 000000000000..2d612434a9a8 Binary files /dev/null and b/content/blog/building-and-publishing-docker-images-to-a-private-amazon-ecr-repository/container-def.png differ diff --git a/content/blog/building-and-publishing-docker-images-to-a-private-amazon-ecr-repository/index.md b/content/blog/building-and-publishing-docker-images-to-a-private-amazon-ecr-repository/index.md new file mode 100644 index 000000000000..3125d3f2201c --- /dev/null +++ b/content/blog/building-and-publishing-docker-images-to-a-private-amazon-ecr-repository/index.md @@ -0,0 +1,214 @@ +--- +title: "Building and Publishing Docker Images to a Private Amazon ECR Repository" +authors: ["cyrus-najmabadi"] +tags: ["Kubernetes", "Infrastructure-as-Code"] +date: "2019-06-18" + +summary: "See how easy it is to build and publish Docker images to a private ECR repository on AWS, and consume them from ECS, Fargate, and EKS services." +meta_image: "RELATIVE_TO_PAGE/pulumi-crosswalk-for-aws.webp" +--- + + +Amazon Elastic Container Registry ([ECR](https://aws.amazon.com/ecr/)) +is a fully-managed Docker container registry that makes it easy for +developers to store, manage, and deploy Docker container images. ECR is +integrated with Amazon Elastic Container Service +([ECS](https://aws.amazon.com/ecs/)), including for Kubernetes +([EKS](https://aws.amazon.com/eks)), simplifying your development to +production workflow, securing access through IAM, and eliminating the +need to operate your own container repositories or worry about scaling +the underlying infrastructure. ECR hosts your images in a highly +available and scalable architecture, allowing you to reliably deploy +containers for your applications. In this article, we'll see how +[Pulumi Crosswalk for AWS]({{< ref "/crosswalk/aws" >}}) lets you use +infrastructure as code to easily build, publish, and pull from private +ECR repositories. + +## A Simple ECS Fargate Service + +Let's see how using Pulumi you can provision an ECR repository, and +build and publish to it, in just a few lines of code. Additional +features such as lifecycle management make it easy to declare policies +specifying how and when stale images should be dropped. Built images can +then be referenced from your ECS services (whether +[EC2,](https://aws.amazon.com/ec2/) [Fargate](https://aws.amazon.com/fargate/), +or [EKS](https://aws.amazon.com/eks)), allowing you to easily version +both your images and your infrastructure with one simple, auditable, +system. + +Let's take a look at this in action. First, we'll just start with a +simple Pulumi program that creates a load balanced Fargate Service that +accessible to the internet, but uses the *public* `nginx` container +image from the Docker Hub: + + // A simple NGINX service, scaled out over two containers. + const nginx = new awsx.ecs.FargateService("nginx", { + cluster, + desiredCount: 2, + taskDefinitionArgs: { + containers: { + nginx: { + image: "nginx", + memory: 128, + portMappings: [new awsx.elasticloadbalancingv2.ApplicationListener("nginx", { port: 80 })], + }, + }, + }, + }); + + export const nginxEndpoint = nginxListener.endpoint; + +Running this give us: + + Updating (teststack): + Type Name Status + + pulumi:pulumi:Stack teststack created + + ├─ awsx:x:elasticloadbalancingv2:ApplicationLoadBalancer nginx created + + │ ├─ awsx:x:elasticloadbalancingv2:ApplicationTargetGroup nginx created + + │ │ └─ aws:elasticloadbalancingv2:TargetGroup nginx created + + │ ├─ awsx:x:elasticloadbalancingv2:ApplicationListener nginx created + ... more output trimmed *** + + Outputs: + nginxEndpoint: { hostname: "********", port: 80 } + + Resources: + + 36 created + + Duration: 3m19s + +We have trimmed the output, since this simple program provisioned 36 AWS +resources, connected them accordingly, and stood up a load balanced ECS +Fargate service that automatically uses cloud deployment best practices. + +Here, through the use of `image: "nginx"` we are letting ECS know that +we want to use [this](https://hub.docker.com/_/nginx/) publicly +available Docker Hub image. ECS supports pulling these images for you by +default and making them available to your services. If you're using a +public image, this works great and no further work is necessary on your +part. + +## Using a Private ECR Repository + +There are many times, however, when you or your organization may not +want to use public images, such as private applications that aren't +meant to be shared with the Internet. The Docker Hub supports private +images, however, if you're already building on AWS, Amazon ECR is a +valuable service that allows you to host those images in your AWS +account, leveraging IAM for secure authentication, and ensuring easy, +fast and secure access from your containers. + +Let's see what that looks like with Pulumi. First, we'll create a simple +`Dockerfile` that starts with the base +[nginx](https://hub.docker.com/_/nginx/) image and slightly modifies it +to contain our own custom `index.html` file: + +The `Dockerfile`: + + FROM nginx + COPY content/index.html /usr/share/nginx/html + +The `index.html` file: + +

Hi from Pulumi!

+ +Now, let's see how we'd update our Pulumi app to build this custom +Docker image, push it to ECR, get the resulting image name, and +reference it from our ECS service (it works the same in both ECS and +EKS): + + // common code from before trimmed out + const repository = new awsx.ecr.Repository("repo"); + + // Invoke 'docker' to actually build the DockerFile that is in the 'app' folder relative to + // this program. Once built, push that image up to our personal ECR repo. + const image = repository.buildAndPushImage("./app") + + const service = new awsx.ecs.FargateService("service", { + // ... common code from before trimmed out + taskDefinitionArgs: { + containers: { + service: { + image: image, + +So let's see what happens when we actually try to run this: + +![Pulumi update in progress](./pulumi-update.gif) + +As you can see Pulumi is actually launching the real `docker` executable +locally to use the `Dockerfile` to build the image. As `docker` runs, +the output is captured and automatically shown in the real-time Pulumi +update display. When the image is finished building, it is pushed by +`docker` itself to the ECR repo. Pulumi safely passes temporary repo +credentials to the `docker` executable so it can login and push the +image up. Finally, once available in ECR, the task-definition and +service are appropriately updated to now reference this new image. ECS +will then ensure that the old services are spun down and the new +services are spun up. + +TL;DR, just run `pulumi up`, and it takes care of all the heavy lifting. +In the end we see: + +![summary results](./container-def.png) + +In less than 30 seconds, Pulumi and Docker built the private image, made +it available on ECR, and properly moved the Service over to using it. +This was all done with a single command, with Pulumi smartly figuring +out at the end of the day exactly what changes needed to be made. From +the above we can see just the creation of the Repository components, and +the updates of the Service to now use it. A nice minimal change that +exactly matches our intuition around what would happen. If necessary, +the `.buildAndPushImage` operation can also take many more options to +control what's happening with `docker`. Options around tagging and +caching can be configured, and the `docker` command line can also just +be augmented if necessary to handle advanced scenarios. + +## Managing ECR Lifecycle Policies + +In practice, an organization may be producing and uploading many images +to their private ECR repositories. This can add up in costs as time goes +on, especially when old images are stored that will never be used again. +To aid with this, Pulumi makes it easy to set up [ECR Lifecycle Policies](https://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html) +to control the lifetime of your images and to easily purge unneeded +images based on flexible criteria to meet your needs. + +As a simple example, here's a way to just remove any untagged images +that are older than one week old: + + // common code from before trimmed out + const repository = new awsx.ecr.Repository("repo", { + lifeCyclePolicyArgs: { + rules: [{ + selection: "untagged", + maximumAgeLimit: 7, + }], + }, + }); + +Now, you can keep your last two weeks of images around if you want them +with all tagged images (like `'latest'`) being preserved. You can +continue pushing rapidly to your repo without having to worry about +manually going and cleaning up the stale garbage in the future. + +## Next Steps + +We've shown how [Pulumi Crosswalk for AWS]({{< ref "/crosswalk/aws" >}}) +can create a tight developer inner +loop for building, publishing, and consuming Docker images, using +private ECR repositories, while keeping all your ECS or EKS services and +tasks updated properly and securely. This can be done with flexible +policies to ensure that your repos contain the images you care about and +don't keep holding onto images you no longer need, and is all possible +from a single Pulumi app with simple commands to keep everything in +sync. + +Pulumi is open source and free to use. For more information on Getting +Started, check out: + +1. [AWS QuickStart]({{< ref "/docs/quickstart/aws" >}}) +2. [Pulumi Crosswalk for AWS Announcement]({{< relref "introducing-pulumi-crosswalk-for-aws-the-easiest-way-to-aws" >}}) +3. [Mapbox IOT-as-Code with Pulumi Crosswalk for AWS]({{< relref "mapbox-iot-as-code-with-pulumi-crosswalk-for-aws" >}}) +4. [Pulumi Crosswalk for AWS Documentation for ECS, EKS, ELB, and more]({{< ref "/docs/reference/crosswalk/aws" >}}) + +We think there's no easier way to do containers in a tight inner +development loop, and we hope you agree! diff --git a/content/blog/building-and-publishing-docker-images-to-a-private-amazon-ecr-repository/pulumi-crosswalk-for-aws.webp b/content/blog/building-and-publishing-docker-images-to-a-private-amazon-ecr-repository/pulumi-crosswalk-for-aws.webp new file mode 100644 index 000000000000..9912e18c6f75 Binary files /dev/null and b/content/blog/building-and-publishing-docker-images-to-a-private-amazon-ecr-repository/pulumi-crosswalk-for-aws.webp differ diff --git a/content/blog/building-and-publishing-docker-images-to-a-private-amazon-ecr-repository/pulumi-update.gif b/content/blog/building-and-publishing-docker-images-to-a-private-amazon-ecr-repository/pulumi-update.gif new file mode 100644 index 000000000000..dd7797906b69 Binary files /dev/null and b/content/blog/building-and-publishing-docker-images-to-a-private-amazon-ecr-repository/pulumi-update.gif differ diff --git a/content/blog/happy-birthday-to-pulumi-open-source/index.md b/content/blog/happy-birthday-to-pulumi-open-source/index.md new file mode 100644 index 000000000000..b77b78d247f4 --- /dev/null +++ b/content/blog/happy-birthday-to-pulumi-open-source/index.md @@ -0,0 +1,96 @@ +--- +title: "Happy Birthday to Pulumi open source!" +authors: ["joe-duffy"] +tags: ["Pulumi"] +date: "2019-06-18" + +summary: "One year ago today we open sourced Pulumi, a new approach to multi-cloud infrastructure as code. And what a year it has been! Let's review it at a glance." +meta_image: "RELATIVE_TO_PAGE/pulumi-birthday.png" +--- + + +One year ago today -- on June 18, 2018 -- +[we open sourced Pulumi]({{< relref "introducing-pulumi-a-cloud-development-platform" >}}), +a new approach to multi-cloud infrastructure as code using your favorite +languages. And what a year it has been! + +Here are some highlights we've added in partnership with the community +since launching: + +- Over 100 [examples](https://github.com/pulumi/examples), + [tutorials]({{< ref "/docs/reference/tutorials" >}}), and a brand new + [Getting Started guide]({{< ref "/docs/quickstart" >}}). +- [A native Kubernetes provider with 100% Kubernetes API/version coverage.]({{< relref "pulumi-a-better-way-to-kubernetes" >}}) +- A steady stream of improvements across + [AWS]({{< ref "/docs/quickstart/aws" >}}), + [Azure]({{< ref "/docs/quickstart/azure" >}}), and + [Google Cloud]({{< ref "/docs/quickstart/gcp" >}}) providers. +- [Pulumi Crosswalk for AWS, a framework with built-in AWS infrastructure best practices.]({{< relref "crosswalk/aws" >}}) +- Over 20 additional providers, including + [CloudFlare](https://github.com/pulumi/pulumi-cloudflare), + [Digital Ocean](https://github.com/pulumi/pulumi-digitalocean), and + [MySQL]({{< relref "managing-your-mysql-databases-with-pulumi" >}}). +- Brought our [Python 3 SDK]({{< ref "/docs/reference/pkg/python" >}}) + to parity with our + [Node.js-based JavaScript and TypeScript SDKs]({{< ref "/docs/reference/pkg/nodejs" >}}). +- [Team and Enterprise SaaS editions for teams managing infrastructure in production.](https://www.pulumi.com/pricing) +- [GitHub, GitLab, Atlassian, and SAML/SSO identity providers.]({{< ref "/docs/reference/service/orgs" >}}) +- [CI/CD integrations with GitHub, GitLab, Codefresh, CircleCI, major clouds, and more.]({{< ref "/docs/reference/cd" >}}) +- [Pluggable secrets management and transitive state encryption.]({{< relref "managing-secrets-with-pulumi" >}}) +- [Pluggable state backends for AWS S3, Azure Blob Store, and Google Cloud Store.]({{< ref "/docs/reference/state" >}}) +- [Tools for managing complex, multi-stack environments, including Terraform integration.]({{< relref "using-terraform-remote-state-with-pulumi" >}}) +- Numerous engine reliability and performance improvements, including parallelism. +- [75 blogs, increasingly focused on end to end solutions we see working with customers.]({{< ref "/blog" >}}) + +In addition to the steady stream of product improvements, the community +has grown fast: + +- **1,000s of cloud engineers** trying out Pulumi across over **1,000 + companies**. +- **1,000 end users** collaborating in our Community Slack -- + including emerging MVPs! +- Open source contributions from **over 100 community members**. +- Nearly **5,000 commits**, across **over 100 open source Git + repositories**. + +What we've enjoyed most is hearing about the innovation you, the end +user and customer, have accomplished thanks to Pulumi's unique approach. +These experiences range from enabling better collaboration between +application and infrastructure engineers; vastly improved productivity; +more secure, robust, and reliable delivery pipelines; and an improved +ability to go to production in multiple clouds, including by leveraging +the cloud native Kubernetes stack. + +A few notable success stories include: + +- **Mercedes-Benz R&D North America** used Python infrastructure as + code to break down team silos between developers and infrastructure + engineers. +- **Tableau** was able to get up and running with Kubernetes in AWS, + using Amazon EKS, and make progress on their journey to bringing + continuous delivery to their organization. +- **Learning Machine** went from 25KLOC YAML to 500 lines of + JavaScript, got containers running in AWS and Kubernetes, and halved + their cloud bill along the way. + [Read more.]({{< relref "delivering-cloud-native-infrastructure-as-code#delivering-cloud-native-infrastructure-for-learning-machine" >}}) +- **Mapbox** built a scalable IoT tracking solution with serverless + Lambdas. [Read more.]({{< relref "mapbox-iot-as-code-with-pulumi-crosswalk-for-aws" >}}) +- Multiple early stage startups, including **Jargon**, a TechStars + company, have used Pulumi to get up and running quickly in the cloud + -- doing in days what used to take weeks. +- **Dozens** of more great stories that we can't wait to share in the + weeks to come! + +We want to sincerely thank our community and our customers and partners +-- without you, the year wouldn't have nearly been as successful. The +best part is that we're only just getting started. Expect another year +of more innovation, growing community engagement, customer success, and +more focus on end to end solutions borne out of experience. + +Whether it's adopting infrastructure as code on your favorite cloud, +deploying containers to Kubernetes, or architecting and executing on +your multi-cloud journey, Pulumi is here for you! + +Sincerely, + +Joe and the Pulumi Team diff --git a/content/blog/happy-birthday-to-pulumi-open-source/pulumi-birthday.png b/content/blog/happy-birthday-to-pulumi-open-source/pulumi-birthday.png new file mode 100644 index 000000000000..9919903d8126 Binary files /dev/null and b/content/blog/happy-birthday-to-pulumi-open-source/pulumi-birthday.png differ diff --git a/content/blog/running-containers-in-aws-the-lowdown-ecs-fargate-and-eks/index.md b/content/blog/running-containers-in-aws-the-lowdown-ecs-fargate-and-eks/index.md new file mode 100644 index 000000000000..32a2ea95f5b0 --- /dev/null +++ b/content/blog/running-containers-in-aws-the-lowdown-ecs-fargate-and-eks/index.md @@ -0,0 +1,223 @@ +--- +title: "Running Containers in AWS, the Lowdown: ECS, Fargate, and EKS" +authors: ["joe-duffy"] +tags: ["AWS", "Kubernetes"] +date: "2019-06-20" + +summary: "We often help customers deploy containers to AWS. Choosing between ECS, Fargate, and EKS isn't always easy -- let's explore the options." +meta_image: "RELATIVE_TO_PAGE/pulumi-crosswalk-for-aws.webp" +--- + + +Amazon offers multiple solutions for running containers in AWS, through +its managed Elastic Container Service (ECS). This includes three major +approaches: ECS managed automatically with Fargate, ECS backed by EC2 +instances, and Elastic Kubernetes Service (EKS), delivering the full +power of Kubernetes. It's not always easy to choose between these, so in +this article we provide some basic guidance on the tradeoffs you'll +encounter when choosing. + +## The Options + +At Pulumi, we work with customers to deploy AWS applications all the +time, from early development to scaling production environments +worldwide, using infrastructure as code and often continuous delivery. +During this, we've run across a breadth of container workloads and +requirements, and developed best practices, which this article distills +into some basic advice. As with any advice, the right answer depends on +your scenario's specific requirements. + +Here are the three major options, roughly speaking from easiest to +hardest: + +## Option 1 - ECS Fargate + +[Amazon ECS with Fargate launch type](https://aws.amazon.com/fargate) allows you to deploy and scale +your containerized workloads, automatically, without needing to manage +clusters of EC2 instances by hand. You focus on your Dockerized +applications, with minimal extra declarative metadata about the +requirements of those applications, and not the details of the +underlying compute itself. One could say this is "serverless +containers." Of course, there are servers running your containers, +however the ECS control plane makes informed decisions on your behalf +about when to add capacity, where, and by how much. + +To run a workload in ECS, you use a standard Dockerfile to author, +build, and publish your container image, and then run that image inside +your ECS cluster. Tasks and services are authored using ECS definitions, +which specify the container image to run, instance count, and any CPU, +memory, networking, and disk requirements your workload has. + +Using Pulumi, these definitions can be easily expressed declaratively in +code, like so: + + import * as awsx from "@pulumi/awsx"; + + // Create a load balancer on port 80 and spin up two instances of Nginx. + const lb = new awsx.elasticloadbalancingv2.ApplicationListener("nginx", { port: 80 }); + const nginx = new awsx.ecs.FargateService("nginx", { + taskDefinitionArgs: { + containers: { + nginx: { + image: "nginx", + memory: 128, + portMappings: [ lb ], + }, + }, + }, + desiredCount: 2, + }); + + // Export the load balancer's address so that it's easy to access. + export const url = lb.endpoint.hostname; + +This example runs 2 load balanced instances of an NGINX web server using +ECS Fargate. + +ECS Fargate is often a great choice when getting started, when you don't +have stringent requirements around cost, and/or if you're a small to +medium sized organization who prefers simpler solutions. Many teams are +successful running it scale too, however Fargate doesn't give you as +much control over persistent storage, privileged containers, custom +scheduling, or special VM types like GPUs or FPGAs. For those, EC2 +backed ECS is a better choice. + +## Option 2 - ECS Backed by EC2 Instances + +[Amazon ECS with EC2 launch type](https://aws.amazon.com/ecs) gives you +similar capabilities to ECS managed by Fargate -- in that you can +deploy containerized workloads, declaratively specify their +requirements, and let ECS do the placement and overall scheduling of +them -- but with full control over the compute environment those +containers run in. That includes control over the precise numbers of +servers, AMIs they are running, and their auto-scaling policies. + +To use an EC2 backed cluster, you will need to +[create a cluster and configure the EC2 launch and autoscaling configurations]({{< ref "/docs/reference/crosswalk/aws/ecs#creating-an-auto-scaling-group-for-ecs-cluster-instances" >}}), +and then simply use the awsx.ecs.EC2Service class to create your service +instead. Other than these differences, the resulting code would look +very similar to Option 1 - ECS Fargate above. + +For sophisticated AWS organizations who already know how to fine tune +and run compute at scale efficiently and cost effectively, managing your +ECS cluster's EC2 instances explicitly is often a good choice. The good +news is that you can easily start with Fargate, and then over time, +shift to managing the EC2 compute by hand if you prefer. Managing your +cluster amounts to managing fleets of EC2 instances, CloudWatch logging, +and standard AWS services. + +## Option 3 - Elastic Kubernetes Service (EKS) + +[Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks) +offers a very different approach to running containerized workloads than +ECS Fargate or EC2. EKS is a fully managed offering that runs Kubernetes +inside of your AWS account, making it easier to operate Kubernetes, in +addition to integrating with many AWS services like ELB for load +balancing, IAM for cluster authentication, and CloudWatch for logging +and diagnostics. Using EKS, you don't need to explicitly provision, +manage, and upgrade the Kubernetes control plane's configuration, +compute, and storage. + +[Kubernetes](https://kubernetes.io) is an open standard for running +containers across a variety of public and private cloud environments. +Most public cloud vendors now offer an EKS-like managed offering, +including [Azure (AKS)]({{< ref "/docs/reference/tutorials/kubernetes/tutorial-aks" >}}), +[Google Cloud (GKE)]({{< ref "/docs/reference/tutorials/kubernetes/tutorial-gke" >}}), +and [Digital Ocean]({{< ref "/docs/reference/pkg/nodejs/pulumi/digitalocean#KubernetesCluster" >}}), +and the availability of on-premises private cloud configurations enables +hybrid cloud for large organizations. Kubernetes in inherently more +complicated to operate than the equivalent ECS solutions mentioned +earlier, because it requires becoming an expert in Kubernetes, which +requires more specialization in its tools and management practices. But +the potential payoff is larger for organizations wanting to go "all in" +on cloud native technologies to facilitate either multi-cloud or hybrid +computing -- challenges most large enterprises are facing today. + +In the EKS case, as with ECS, we continue using standard Dockerfiles, +however we use the Kubernetes object model to configure and run +workloads. Instead of task definitions, you use +[Kubernetes objects like Namespaces, Pods, Deployments, and Services](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/). +This full API is available to specify in code using Pulumi, like so: + + import * as eks from "@pulumi/eks"; + import * as k8s from "@pulumi/kubernetes"; + + // Create an EKS cluster with the default configuration. + const cluster = new eks.Cluster("my-cluster"); + + // Deploy a small canary service (NGINX), to test that the cluster is working. + const appName = "my-app"; + const appLabels = { appClass: appName }; + const deployment = new k8s.apps.v1.Deployment(`${appName}-dep`, { + metadata: { labels: appLabels }, + spec: { + replicas: 2, + selector: { matchLabels: appLabels }, + template: { + metadata: { labels: appLabels }, + spec: { + containers: [{ + name: appName, + image: "nginx", + ports: [{ name: "http", containerPort: 80 }] + }], + } + } + }, + }, { provider: cluster.provider }); + const service = new k8s.core.v1.Service(`${appName}-svc`, { + metadata: { labels: appLabels }, + spec: { + type: "LoadBalancer", + ports: [{ port: 80, targetPort: "http" }], + selector: appLabels, + }, + }, { provider: cluster.provider }); + + // Export the URL for the load balanced service. + export const url = service.status.loadBalancer.ingress[0].hostname; + + // Export the cluster's kubeconfig. + export const kubeconfig = cluster.kubeconfig; + +Like the ECS example earlier, this spins up 2 load balanced instances of +the NGINX web server. + +You will find that the entirety of Kubernetes is more feature rich and +offers more control over scheduling and scaling your workloads, but with +that richness also comes added complexity that will increase training, +and time to ramp up, in addition to ongoing maintenance costs. To learn +more about Pulumi's support for Kubernetes, [go here]({{< relref "pulumi-a-better-way-to-kubernetes" >}}). + +## Private ECR Container Registries + +In all of these cases, [Amazon Elastic Container Registry (ECR)]({{< ref "/docs/reference/crosswalk/aws/ecr" >}}) +lets you publish +Docker container images to a privately hosted repository inside your AWS +account. The benefit of this is that images are stored within your AWS +account, where access is governed by IAM and, where they are stored +closer to your workloads (maximizing push/pull efficiency). This is an +alternative approach to, say, publishing images to the Docker Hub which +entails a different authentication and pushing and pulling images over +the Internet, where performance can be an issue. + +## Next Steps + +Pulumi Crosswalk for AWS supports three main options for running +containers in AWS -- ECS Fargate, ECS with EC2 instances, and EKS -- +each of which integrates deeply with other AWS services like IAM, ELB, +and CloudWatch. It's possible to use any of these services without +Pulumi, but there are [many benefits to Pulumi's infrastructure as code](https://www.pulumi.com/why-pulumi/). + +In short, to get your containers up on AWS, in an easy yet +production-ready way, [get started for free with Pulumi for AWS today]({{< ref "/docs/quickstart/aws" >}})! + +After getting started, here are some additional resources to go deeper +on specific topics: + +- [Getting Started with ECS]({{< ref "/docs/reference/crosswalk/aws/ecs" >}}) +- [Getting Started with EKS]({{< ref "/docs/reference/crosswalk/aws/eks" >}}) +- [Getting Started with ECR]({{< ref "/docs/reference/crosswalk/aws/ecr" >}}) + - [Using ECR from ECS Fargate or EC2]({{< ref "/docs/reference/crosswalk/aws/ecs#building-and-publishing-docker-images-automatically" >}}) + - [Using ECR from EKS]({{< ref "/docs/reference/crosswalk/aws/eks#using-an-ecr-container-image-from-an-eks-kubernetes-deployment" >}}) + - [Building and Publishing Docker Images to a Private Amazon ECR Repository]({{< relref "building-and-publishing-docker-images-to-a-private-amazon-ecr-repository" >}}) diff --git a/content/blog/running-containers-in-aws-the-lowdown-ecs-fargate-and-eks/pulumi-crosswalk-for-aws.webp b/content/blog/running-containers-in-aws-the-lowdown-ecs-fargate-and-eks/pulumi-crosswalk-for-aws.webp new file mode 100644 index 000000000000..9912e18c6f75 Binary files /dev/null and b/content/blog/running-containers-in-aws-the-lowdown-ecs-fargate-and-eks/pulumi-crosswalk-for-aws.webp differ diff --git a/content/blog/using-terraform-remote-state-with-pulumi/index.md b/content/blog/using-terraform-remote-state-with-pulumi/index.md index 83e14a3a31f0..46d026f6ea75 100644 --- a/content/blog/using-terraform-remote-state-with-pulumi/index.md +++ b/content/blog/using-terraform-remote-state-with-pulumi/index.md @@ -2,7 +2,7 @@ title: "Using Terraform Remote State with Pulumi" authors: ["paul-stack"] tags: ["Terraform-Migration", "Infrastructure-as-Code"] -date: "2019-07-07" +date: "2019-06-07" summary: "Pulumi can co-exist with other infra tools, including consuming Terraform remote and local state outputs!" --- @@ -20,22 +20,19 @@ by different teams. For example, it's common to see an application team deploying into a VPC owned and managed by a network operations team. Pulumi supports -[this kind of workflow]({{< ref "/docs/reference/organizing-stacks-projects/#inter-stack-dependencies" >}}) -natively using -the[`StackReference`]({{< ref "/docs/reference/pkg/nodejs/pulumi/pulumi/#StackReference" >}}) +[this kind of workflow]({{< ref "/docs/reference/organizing-stacks-projects#inter-stack-dependencies" >}}) +natively using the [`StackReference`]({{< ref "/docs/reference/pkg/nodejs/pulumi/pulumi#StackReference" >}}) type from the Pulumi SDK. Integration with the most popular cloud-specific tools have been supported by Pulumi since the earliest days: -- The - [`aws.cloudformation.getStack()`]({{< ref "/docs/reference/pkg/nodejs/pulumi/aws/cloudformation/#getStack" >}}) +- The [`aws.cloudformation.getStack()`]({{< ref "/docs/reference/pkg/nodejs/pulumi/aws/cloudformation#getStack" >}}) function can be used to obtain the outputs from a CloudFormation Stack. -- The - [`get`]({{< ref "/docs/reference/pkg/nodejs/pulumi/azure/core/#TemplateDeployment-get" >}}) +- The [`get`]({{< ref "/docs/reference/pkg/nodejs/pulumi/azure/core#TemplateDeployment-get" >}}) method of the - [`azure.core.TemplateDeployment`]({{< ref "/docs/reference/pkg/nodejs/pulumi/azure/core/#TemplateDeployment" >}}) + [`azure.core.TemplateDeployment`]({{< ref "/docs/reference/pkg/nodejs/pulumi/azure/core#TemplateDeployment" >}}) class can be used to obtain the outputs of an ARM Template Deployment. @@ -176,7 +173,6 @@ Pulumi is free and open-source, and you can [get started today]({{< ref "/docs/q To learn more about migrating from Terraform to Pulumi, check out [From Terraform to Infrastructure as Software]({{< relref "from-terraform-to-infrastructure-as-software" >}}) -and the [Terraform comparison -documentation]({{< ref "/docs/reference/vs/terraform/" >}}), or join us in +and the [Terraform comparison documentation]({{< ref "/docs/reference/vs/terraform" >}}), or join us in the [Pulumi Community Slack](https://slack.pulumi.io/) to discuss with the Pulumi community. diff --git a/package-lock.json b/package-lock.json index 6a72316585e0..73e1209ebb7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -433,6 +433,12 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -496,6 +502,12 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true + }, "caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -1444,8 +1456,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -1466,14 +1477,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1488,20 +1497,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -1618,8 +1624,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -1631,7 +1636,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1646,7 +1650,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1654,14 +1657,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -1680,7 +1681,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -1761,8 +1761,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -1774,7 +1773,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -1860,8 +1858,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -1897,7 +1894,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -1917,7 +1913,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -1961,14 +1956,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -2593,6 +2586,12 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=", + "dev": true + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -2835,6 +2834,15 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "node-emoji": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", + "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "dev": true, + "requires": { + "lodash.toarray": "^4.4.0" + } + }, "node-releases": { "version": "1.1.23", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.23.tgz", @@ -2930,6 +2938,12 @@ "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", "dev": true }, + "normalize.css": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", + "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==", + "dev": true + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -3402,6 +3416,76 @@ "postcss": "^7.0.0" } }, + "postcss-functions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-functions/-/postcss-functions-3.0.0.tgz", + "integrity": "sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4=", + "dev": true, + "requires": { + "glob": "^7.1.2", + "object-assign": "^4.1.1", + "postcss": "^6.0.9", + "postcss-value-parser": "^3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-2.0.1.tgz", + "integrity": "sha512-8XQGohCbj6+kq8e3w6WlexkGaSjb5S8zoXnH49eB8JC6+qN2kQW+ib6fTjRgCpRRN9eeFOhMlD0NDjThW1DCBg==", + "dev": true, + "requires": { + "camelcase-css": "^2.0.1", + "postcss": "^7.0.14" + } + }, "postcss-load-config": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz", @@ -3526,6 +3610,16 @@ } } }, + "postcss-nested": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-4.1.2.tgz", + "integrity": "sha512-9bQFr2TezohU3KRSu9f6sfecXmf/x6RXDedl8CHF6fyuyVW7UqgNMRdWMHZQWuFY6Xqs2NYk+Fj4Z4vSOf7PQg==", + "dev": true, + "requires": { + "postcss": "^7.0.14", + "postcss-selector-parser": "^5.0.0" + } + }, "postcss-normalize-charset": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", @@ -4413,6 +4507,92 @@ } } }, + "tailwindcss": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-1.0.4.tgz", + "integrity": "sha512-+1NNPW+U83k6DV/uUOnsfmX86Cfb8N87fiuN0cX0mEi2sZUpglLzZqlXtP8FD9Hlne5H1UhlS8tajz+F9SSxjA==", + "dev": true, + "requires": { + "autoprefixer": "^9.4.5", + "bytes": "^3.0.0", + "chalk": "^2.4.1", + "fs-extra": "^8.0.0", + "lodash": "^4.17.11", + "node-emoji": "^1.8.1", + "normalize.css": "^8.0.1", + "postcss": "^7.0.11", + "postcss-functions": "^3.0.0", + "postcss-js": "^2.0.0", + "postcss-nested": "^4.1.1", + "postcss-selector-parser": "^6.0.0", + "pretty-hrtime": "^1.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "fs-extra": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.0.1.tgz", + "integrity": "sha512-W+XLrggcDzlle47X/XnS7FXrXu9sDo+Ze9zpndeBxdgv88FHLm1HtmkhEwavruS6koanBjp098rUpHs65EmG7A==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "postcss-selector-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", + "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",