Giter Site home page Giter Site logo

oci-arch-ci-cd's Introduction

oci-arch-ci-cd

Quick delivery of software has become a competitive advantage for companies. The automation of development processes facilitates speed and consistency, which led to the rise of continuous integration (CI) and continuous delivery and deployment (CD) pipelines. Jenkins is a popular product among Oracle Cloud Infrastructure customers that can automate all phases of CI and CD.

In this reference architecture, Jenkins is hosted on Oracle Cloud Infrastructure to centralize build automation and scale the deployment by using Oracle Cloud Infrastructure Registry and Container Engine for Kubernetes. GitHub is used to manage source code.

For details of the architecture, see Set up a CI/CD pipeline for cloud deployments

Terraform Provider for Oracle Cloud Infrastructure

The OCI Terraform Provider is now available for automatic download through the Terraform Provider Registry. For more information on how to get started view the documentation and setup guide.

Deploy Using Oracle Resource Manager

  1. Click Deploy to Oracle Cloud

    If you aren't already signed in, when prompted, enter the tenancy and user credentials.

  2. Review and accept the terms and conditions.

  3. Select the region where you want to deploy the stack.

  4. Follow the on-screen prompts and instructions to create the stack.

  5. After creating the stack, click Terraform Actions, and select Plan.

  6. Wait for the job to be completed, and review the plan.

    To make any changes, return to the Stack Details page, click Edit Stack, and make the required changes. Then, run the Plan action again.

  7. If no further changes are necessary, return to the Stack Details page, click Terraform Actions, and select Apply.

Deploy Using the Terraform CLI

Clone the Module

Now, you'll want a local copy of this repo. You can make that with the commands:

git clone https://github.com/oracle-quickstart/oci-arch-ci-cd
cd oci-arch-ci-cd
ls

Prerequisites

First off, you'll need to do some pre-deploy setup. That's all detailed here.

Secondly, create a terraform.tfvars file and populate with the following information:

# Authentication
tenancy_ocid         = "<tenancy_ocid>"
user_ocid            = "<user_ocid>"
fingerprint          = "<finger_print>"
private_key_path     = "<pem_private_key_path>"

# Region
region = "<oci_region>"

# Compartment
compartment_ocid = "<compartment_ocid>"

Deploy:

terraform init
terraform plan
terraform apply

Post-Deployment Setup

Step 1: Retrieve the auto-generated SSH keys

1.1. If using Resource Manager

Within the Stack, go to Jobs -> open the 'Apply' job -> Outputs -> generated_ssh_private_key -> click 'Unlock'
WARNING: the displayed key is not ideally formatted. Here is a sample tool which will quickly format the key for you.

1.2 If using OCI CLI, run:

terraform console
nonsensitive(tls_private_key.public_private_key_pair.private_key_pem)

Step 2: Configure oci-cli and sudo user on jenkins instance

Go to OCI console -> Compute -> Instances.

You should be able to see the instance jenkins-instance

Copy the public-ip of the instance. Log in to the instance using below command.

ssh -i <path-to-ssh-private-key> opc@<public-ip-of-jenkins-instance>

Once you are logged in, make sure oci-cli is installed using:

oci -v

Next, run the command oci setup config

Press Enter when prompted for a location for config file.

Press Enter when prompted for directory name to accept the default.

Enter the details about user OCID, tenancy OCID and region.

Enter Y for New RSA key pair.

Press Enter and accept default options for directories for keys and name for the keys.

Press Enter when prompted for passphrase so as to leave it blank.

Verify all the files exists by checking in -> cd /home/opc/.oci and then ls.

You should see these files.

Run cat config and make sure all the details about tenancy are correct.

Now, do cat oci_api_key_public.pem and copy the contents of the file.

Login to OCI console, go to your profile and then your username.

Click on Add Public Key and paste the contents of the file copied in last step.

Make sure the fingerprint is generated and also check it is same as the one in Jenkins Instance /home/opc/.oci/config file.

Next, to add sudo user to Jenkins Server, on Jenkins Instance, do

sudo visudo -f /etc/sudoers.d/filename

Press i for insert mode. Now we just need to include the line listed below in our file:

jenkins ALL=(ALL) NOPASSWD: ALL

Save and Exit from edit mode,

Press ESC and type :wq! and hit Enter. You should be out of the edit mode.

We are done.

Step 2: Configure OCI tenancy details on Jenkins UI

Go to OCI console -> Compute -> Instances.

You should be able to see the instance jenkins-instance

Copy the public-ip of the instance. Open a browser and enter

<public-ip-of-the-instance>:8080

This should give you a Jenkins UI. Login using username as admin and password as Admin123.

On the Jenkins UI, In Manage Jenkins screen on the left, Click Configure System, scroll down and locate `Cloud`.

Click on 'Add a new cloud'. Now, under drop down select 'Oracle Cloud Infrastructure Compute'. 

New dialog box will appear.

Enter 'Name: <Use easy to remember name>'. 
Next to 'Credentials', click on 'Add' and from the dropdown select 'Jenkins'.

This opens up a dialog box. Keep the 'Domain' as it is. 
For Kind, Choose 'Oracle Cloud Infrastructure Credentials'.

For rest, Fill out the dialog box:

Name: Use easy to remember name
Fingerprint: Copy/paste OCI_api_key_fingerprint value from the config file saved in step 1.
APIKey: Copy/paste oci_api_key.pem file content saved in /home/opc/.oci folder in step 1.
PassPhrase: Leave empty
Tenant Id: Copy/paste Tenant OCID.
User Id: Copy/paste User OCID.
ID: Leave empty
Description: Leave empty
Region: Type your region Name (Shown in OCI console window, us-ashburn-1 etc)

Click Verify Credentials and make sure for ‘Successful’ message. We have now verified connectivity to OCI via the Jenkins compute node.

Click on Add.

Finally, come down and make sure to click on Save

Step 3: Configure Github webhook

Go to the repo https://github.com/KartikShrikantHegde/jenkins-helloworld. Fork it.

On the right side, Go to Settings. Then on the left, click on Webhooks.

You should see an option to Add webhook. click on it.

For Payload URL enter -> http://<public-ip-of-the-instance>:8080/github-webhook/

For Content type, choose -> application/json

Leave the secret field blank.

select send me everything for the field -> Which events would you like to trigger this webhook

Add webhook and you are done.

Step 4: Generate Github token

Now click on your github account profile, and click on Settings.

On the left side, you will see an option Developer settings. Click on it.

Again on the left, click on Personal access tokens. Click Generate new token.

Enter a note, select all the options under Select scopes and click on Generate token at the bottom.

This will generate a one time token. Copy and save it for future steps.

Step 5: Add the Github token to Jenkins UI

On the Jenkins UI, In Manage Jenkins option on the left , Click Configure System.

Scroll down a bit and you will see GitHub section.

Under that, Click on Add Github Server and then again Github Server from the dropdown. This opens up a window.

Enter the details:

Name -> Specify a name

API URL -> leave the default url as it is.

Credentials -> Click on Add button and then Jenkins under the dropdown. This opens a new window.

Here, change the Kind to Secret Text.

Under Secret -> Enter the access token that was generated in the previous step 4. Leave rest of the fields blank.

Under Credentials, change option from none to Secret text.

Click on Test connection and it should show Credentials verified for <user>. So now our Jenkins can access our repo.

Check right mark on the Manage hooks

Go down to the bottom and make sure to click on Save.

Step 6: Generate OCIR token

Login to OCI console.

Click on your Profile -> User Settings. On the bottom left, click on Auth Tokens.

Click on Generate Token.

Provide a discription and then hit Generate Token. This will generate a token. Make sure to copy the token for future steps.

Step 7: Update deployment files and copy to jenkins instance

In your local working directory, you should be able to see 2 files hello-deploy.sh and hello.yaml along with other terraform files.

Open both the files and add in details specific to your tenancy.

For hello-deploy.sh, update details for these fields:

<region-prefix-name> -> eg: iad.ocir.io (for ashburn region)

<username> -> <your-tenancy-namespace>/identitycloudservice/<your-oci-user-email-here> (look for namespace in tenancy details on your OCI console for <your-tenancy-namespace>)

<ocir-token> -> the token we generated in previous step 6

For hello.yaml, update:

<region-prefix-name> - eg: iad.ocir.io (for ashburn region)

<your-tenancy-namespace> -> (look for namespace in tenancy details on your OCI console for <your-tenancy-namespace>)

Once updated, lets copy these files into jenkins instance.

From your local working directory where you have these files stored, copy the files into jenkins server using below commands.

scp -i <path-to-ssh-private-key> hello-deploy.sh opc@<public-ip-of-jenkins-instance>:/home/opc

scp -i <path-to-ssh-private-key> hello.yml opc@<public-ip-of-jenkins-instance>:/home/opc

Now, login to your instance -> ssh -i <path-to-ssh-private-key> opc@<public-ip-of-jenkins-instance>

Finally, copy both hello-deploy.sh and hello.yml to /var/lib/jenkins as:

sudo cp hello.yml /var/lib/jenkins

sudo cp hello-deploy.sh /var/lib/jenkins

Step 8: Update Jenkinsfile in Github repo

Go to the forked Github repo from https://github.com/KartikShrikantHegde/jenkins-helloworld.

Next, in the repo, you should be able to find Jenkinsfile. Let's update the Jenkinsfile.

In the Jenkinsfile, go to stage('Push image to OCIR') and update details related to your tenancy:

<username> -> <your-tenancy-namespace>/identitycloudservice/<your-oci-user-email-here> (look for namespace in tenancy details on your OCI console for <your-tenancy-namespace>)

<ocir-token> -> the token we generated in step 6

<region-prefix-name> -> eg: iad.ocir.io (for ashburn region)

<your-tenancy-namespace> -> (look for namespace in tenancy details on your OCI console for <your-tenancy-namespace>)

Edit all the details and save the file.

Step 9: Install kubectl and configure kube-config on Jenkins

ssh into jenkins instance and install and verify kubectl using below single command.

curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl;chmod +x ./kubectl;sudo mv ./kubectl /usr/local/bin/kubectl;kubectl version --client

Now, to setup kubeconfig, go to your OCI tenancy. On the left hand side click on Developer Services. Select Container Clusters (OKE).

Click on the cluster created by terraform earlier.

On the top, click on Access Kubeconfig and run the commands specified (make sure you are inside the jenkins instance to run the commands).

Once done, verify you can access the k8s nodes, by typing:

kubectl get nodes

You see details of the nodes running in the cluster.

Step 10: Create pipeline using Blue Ocean

Finally, with all the configurations done, lets create the pipeline.

On the Jenkins UI,(refer step 2 on how to access Jenkins UI), on the left hand side, you should see Open Blue Ocean. Click on it. It opens a new page.

Select Create a new Pipeline. Next select GitHub. If it asks for a token provide the Github token we generated in step 4.

Next, select your github profile. Search for the repo (jenkins-helloworld) you had forked and made the changes.

Hit Create Pipeline.

This creates a pipeline and starts the build, test and deploy steps. Once completed (indicated by green tick), you can go back to jenkins instance and run below command.

kubectl get services

You see details of the services running on the nodes in the cluster.

For the hello-service load balancer that you just deployed, you will see: the external IP address of the load balancer (for example, 129.146.147.91) the port number.

Open a new browser window and enter the url to access the hello application in the browser's URL field. For example, http://129.146.147.91

You should be able to access the application.

Fron now on, any changes you make to the github code, triggers a new build and deploy by jenkins. This completes the CI/CD cycle.

Destroy the Deployment

When you no longer need the deployment, you can run this command to destroy it:

terraform destroy

CI/CD Architecture

oci-arch-ci-cd's People

Contributors

benofben avatar kartikshrikanthegde avatar lfeldman avatar nugoncal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oci-arch-ci-cd's Issues

Job failed with Error Message: Invalid nodeShape: Node shape and image are not compatible.

Error: 400-InvalidParameter
Provider version: 4.51.0, released on 2021-11-03.
Service: Containerengine Node Pool
Error Message: Invalid nodeShape: Node shape and image are not compatible.
OPC request ID: 8677164efd908f4deb5a5d4201db8c16/3BB3AEF3FB0EF4D50F15D34062B7B615/01394B3157B68DB1A72651172472315A
Suggestion: Please Update the parameter(s) in the Terraform config as per error message Invalid nodeShape: Node shape and image are not compatible.

Need documentation on how to ssh to Jenkins server with code created public-private key-pair

When the default installation options are accepted, the installation completes successfully. ie. The Jenkins server is created and is accessible via the browser. But there are no instructions on how to retrieve the private key that would be needed to ssh to the Jenkins server.
Do I use the private_key_pem value from the state file to construct the private key ?
I tried ssh using that and its looking for a passphrase.

Problems with terraform plan

I've cloned the repo, created file terraform.tfvars and I get this message when I type terraform plan:
rror: Invalid index

│ on modules/jenkins-master/main.tf line 41, in resource "oci_core_instance" "TFJenkinsMaster":
│ 41: source_id = data.oci_core_images.InstanceImageOCID.images[0].id
│ ├────────────────
│ │ data.oci_core_images.InstanceImageOCID.images is empty list of object

Any idea?
Thanks!

deployment via custom ssh public key fails

Terraform deployment with personal ssh key pair (public key) fails. Error message
Error: file provisioner error
with module.jenkins.module.jenkins-controller.null_resource.TFJenkinsControllerConfig_via_public_ip[0],
on .terraform/modules/jenkins/modules/jenkins-controller/main.tf line 105, in resource "null_resource" "TFJenkinsControllerConfig_via_public_ip"
105: provisioner "file" {
timeout - last error: SSH authentication failed ([email protected]:22): ssh:
handshake failed: ssh: unable to authenticate, attempted methods [none
publickey], no supported methods remain

Executing with Resource Manager fails on sudo yum install -y xmlstarlet

The setup.sh script fails with:

sudo yum install -y xmlstarlet
module.jenkins-master.oci_core_instance.TFJenkinsMaster (remote-exec): Error: Nothing to do

Executing manually on a separate Oracle Linux 7.9 instance shows:

sudo yum install -y xmlstarlet
Loaded plugins: langpacks, ulninfo
No package xmlstarlet available.
Error: Nothing to do

To make it work, I had to change:
from:
sudo yum install -y xmlstarlet
to:

sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sleep 10
sudo yum install -y xmlstarlet

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.