├── .gitignore ├── Jenkinsfile ├── LICENSE ├── README.md ├── main.tf ├── provider.tf └── variables.tf /.gitignore: -------------------------------------------------------------------------------- 1 | */terraform.tfstate 2 | */terraform.tfstate.backup 3 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!groovy 2 | 3 | // Build Parameters 4 | properties([ parameters([ 5 | string( name: 'AWS_ACCESS_KEY_ID', defaultValue: ''), 6 | string( name: 'AWS_SECRET_ACCESS_KEY', defaultValue: '') 7 | ]), pipelineTriggers([]) ]) 8 | 9 | // Environment Variables 10 | env.AWS_ACCESS_KEY_ID = AWS_ACCESS_KEY_ID 11 | env.AWS_SECRET_ACCESS_KEY = AWS_SECRET_ACCESS_KEY 12 | 13 | node { 14 | env.PATH += ":/opt/terraform_0.7.13/" 15 | 16 | stage ('Checkout') { 17 | checkout scm 18 | } 19 | 20 | stage ('Terraform Plan') { 21 | sh 'terraform plan -no-color -out=create.tfplan' 22 | } 23 | 24 | // Optional wait for approval 25 | input 'Deploy stack?' 26 | 27 | stage ('Terraform Apply') { 28 | sh 'terraform apply -no-color create.tfplan' 29 | } 30 | 31 | stage ('Post Run Tests') { 32 | echo "Insert your infrastructure test of choice and/or application validation here." 33 | sleep 2 34 | sh 'terraform show' 35 | } 36 | 37 | stage ('Notification') { 38 | mail from: "jenkins@mycompany.com", 39 | to: "devopsteam@mycompany.com", 40 | subject: "Terraform build complete", 41 | body: "Jenkins job ${env.JOB_NAME} - build ${env.BUILD_NUMBER} complete" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Datapipe, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## CI/CD Pipeline-as-code example 2 | 3 | Accompanying blog post: https://www.datapipe.com/blog/2017/03/30/cicd-pipelines-as-code/ 4 | 5 | This is an example repository to highlight the basic value of pipelines-as-code using Jenkins and Terraform. 6 | 7 | The Terraform stack (`main.tf`), consists of a single Auto-Scaling Group + Launch Configuration for a single Ubuntu instance. Customize the `variables.tf` file accordingly. A Default VPC is assumed to be present in the target region. 8 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | # This stack assumes that a Default VPC is present 2 | 3 | data "aws_ami" "ubuntu" { 4 | most_recent = true 5 | filter { 6 | name = "name" 7 | values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"] 8 | } 9 | filter { 10 | name = "virtualization-type" 11 | values = ["hvm"] 12 | } 13 | owners = ["099720109477"] # Canonical 14 | } 15 | 16 | resource "aws_launch_configuration" "test-lc" { 17 | name_prefix = "test-lc-" 18 | image_id = "${data.aws_ami.ubuntu.id}" 19 | instance_type = "${var.instance_type}" 20 | 21 | key_name = "${var.key_name}" 22 | security_groups = [ "${aws_security_group.instance.id}" ] 23 | 24 | lifecycle { 25 | create_before_destroy = true 26 | } 27 | } 28 | 29 | resource "aws_autoscaling_group" "test-asg" { 30 | name = "test-asg" 31 | min_size = 1 32 | max_size = 1 33 | launch_configuration = "${aws_launch_configuration.test-lc.id}" 34 | availability_zones = ["${var.region}a"] 35 | } 36 | 37 | resource "aws_security_group" "instance" { 38 | name = "test-sg" 39 | description = "Allow traffic for test-asg instances" 40 | 41 | ingress { 42 | from_port = 22 43 | to_port = 22 44 | protocol = "tcp" 45 | cidr_blocks = [ "0.0.0.0/0" ] 46 | } 47 | 48 | egress { 49 | from_port = 0 50 | to_port = 65535 51 | protocol = "tcp" 52 | cidr_blocks = [ "0.0.0.0/0" ] 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "${var.region}" 3 | } 4 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "region" { default = "us-west-2" } 2 | variable "instance_type" { default = "t2.micro" } 3 | variable "key_name" { default = "my_ssh_key" } 4 | --------------------------------------------------------------------------------