Skip to content

Commit 5c89619

Browse files
authored
Merge pull request #821 from oracle-devrel/azure-devops-oke
Azure devops oke
2 parents 36462a2 + 40494dd commit 5c89619

File tree

7 files changed

+256
-0
lines changed

7 files changed

+256
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
FROM mendhak/http-https-echo
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
<!--
2+
Copyright (c) 2024 Oracle and/or its affiliates.
3+
4+
The Universal Permissive License (UPL), Version 1.0
5+
6+
Subject to the condition set forth below, permission is hereby granted to any
7+
person obtaining a copy of this software, associated documentation and/or data
8+
(collectively the "Software"), free of charge and under any and all copyright
9+
rights in the Software, and any and all patent rights owned or freely
10+
licensable by each licensor hereunder covering either (i) the unmodified
11+
Software as contributed to or provided by such licensor, or (ii) the Larger
12+
Works (as defined below), to deal in both
13+
14+
(a) the Software, and
15+
(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
16+
one is included with the Software (each a "Larger Work" to which the Software
17+
is contributed by such licensors),
18+
19+
without restriction, including without limitation the rights to copy, create
20+
derivative works of, display, perform, and distribute the Software and make,
21+
use, sell, offer for sale, import, export, have made, and have sold the
22+
Software and the Larger Work(s), and to sublicense the foregoing rights on
23+
either these or other terms.
24+
25+
This license is subject to the following condition:
26+
The above copyright notice and either this complete permission notice or at
27+
a minimum a reference to the UPL must be included in all copies or
28+
substantial portions of the Software.
29+
30+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36+
SOFTWARE.
37+
-->
38+
39+
## Building and Deploying to OKE with Azure DevOps
40+
41+
There are two ways (at least) to build and deploy to OKE from Azure DevOps:
42+
<ul>
43+
<li>Use OCI VM as Azure parallel job self-hosted build agent that will run as <code>instance-principal</code> and hence no OCI credentials are needed to be shared with Azure DevOps. Here <code>kubectl</code> and OCI native tooling like <code>oci cli</code> can be used in pipelines.</li>
44+
<br>
45+
<li>Use Azure DevOps native <code>tasks</code> that can run as either Azure-hosted or as self-hosted Azure parallel jobs. Credentials will be stored to Azure DevOps.</li>
46+
</ul>
47+
48+
<p>
49+
For this example I've used the second option. I'm also using a self-hosted agent/runner on OCI but that's just because I can use the <code>always-free</code> VM instance for it as part of the default OCI subscription and I don't have any Azure-hosted agents available in my Azure subscription. Technically that does not matter since the agent is a vanilla Oracle Linux VM instance and does not contain any customizations whatsover to do the pipeline work (it could however, but it does not).
50+
51+
## Copy the files to the Azure DevOps repo
52+
53+
To make this build and deploy to OKE to work is not a big task. First copy the files in this repo to you empty Azure DevOps project repo.
54+
55+
## Create OCIR repository for the test image
56+
57+
Before building the Docker image repo needs to be created under the desired <code>compartment</code>. This can be easily done using OCI Cloud UI. Name the repository as <b><i>Azure-test</i></b>, for example.
58+
59+
<p>
60+
Then modify the <code>deployment.yaml</code> <a href="https://github.com/oracle-devrel/technology-engineering/blob/azure-devops-oke/app-dev/devops/azure-devops-oke/deployment.yaml#L19">line 19</a> by replacing the &lt;TENANCY_NAMESPACE&gt; with yours and if you gave another name for the OCIR repo then modify also that here, too. Modify also the <code>region</code> if using some other OCI region than <b><i>fra.ocir.io</i></b>.
61+
62+
<p>
63+
To be able to do <code>Docker login</code> to the repo create <code>auth token</code> for your OCI user unless you already have one.
64+
65+
## Create OKE cluster (or use existing) and setup Service Account for Azure DevOps
66+
67+
Using Cloud UI and OKE Quick create setup a new Kubernetes cluster in OCI for this example. Alternatively you can also use an existing one. Make sure the OKE cluster has <code>public</code> API endpoint access for <code>kubectl</code>.
68+
69+
<p>
70+
Once the OKE cluster is up and running with <code>kubectl</code> access setup the Service Account for Azure DevOps by following this guide:
71+
<a href="https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengaddingserviceaccttoken.htm" target="_NEW">https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengaddingserviceaccttoken.htm</a>.
72+
73+
<p>
74+
Name the secret <b><i>oke-kubeconfig-azure-token</i></b> as in <code>azure-token.yaml</code> <a href="https://github.com/oracle-devrel/technology-engineering/blob/azure-devops-oke/app-dev/devops/azure-devops-oke/azure-token.yaml#L4" target="_NEW">line 14</a>.
75+
76+
## Setup Azure DevOps OCI connections for OKE and OCIR
77+
78+
To make the Azure DevOps pipeline to work with OCIR and OKE two <code>Service Connections are</code> needed with the following settings:
79+
<ul>
80+
<li>OCIR</li>
81+
<ul>
82+
<li>Type: Docker Registry</li>
83+
<li>Registry Type: Others</li>
84+
<li>Docker ID: Your OCI user e.g. <i>&lt;TENANCY_NAMESPACE&gt;/oracleidentitycloudservice/[email protected]</i></li>
85+
<li>Docker Password: Your OCI user's auth token</li>
86+
<li>Service connection name: OCIR</li>
87+
<li>Grant access permissions to all pipelines: YES</li>
88+
</ul>
89+
<li>OKE</li>
90+
<ul>
91+
<li>Type: Kubernetes</li>
92+
<li>Authentication method: Service Account</li>
93+
<li>Server URL: OKE cluster server address from your <i>~/.kube/config</i> e.g. <i>https://145.144.233.100:6443</i></li>
94+
<li>Authorization Secret: Get the secret JSON by doing <i>kubectl get secret oke-kubeconfig-azure-token -n kube-system -o json</i> and paste it here</li>
95+
<li>Service connection name: OKE</li>
96+
<li>Grant access permission to all pipelines: YES</li>
97+
</ul>
98+
</ul>
99+
100+
101+
## Create env vars for the build pipeline
102+
103+
Create a pipeline from existing Azure DevOps pipeline file by selecting the project repo and the file <b><i>azure-pipelines.yaml</i></b>.
104+
105+
Edit the created pipeline and select <code>Variables</code> to create them as follows:
106+
107+
<ul>
108+
<li>CONTAINER_REGISTRY: OCIR</li>
109+
<li>CONTAINER_REPOSITORY: Use the same name as in the <code>deployment.yaml</code> <a href="https://github.com/oracle-devrel/technology-engineering/blob/azure-devops-oke/app-dev/devops/azure-devops-oke/deployment.yaml#L19">line 19</a> but <b><i>without</i></b> the <code>region</code> and the <code>tag</code> ("1" in the example YAML file) e.g. <b><i>&lt;TENANCY_NAMESPACE&gt;/azure-test</i></b></li>
110+
<li>containerImageFullNameForK8sDeploy: The same as above but with the OCI region e.g. <b><i>fra.ocir.io/&lt;TENANCY_NAMESPACE&gt;/azure-test</i></b></li>
111+
<li>K8S_CONNECTION_NAME: OKE</li>
112+
<li>K8S_NAMESPACE: default</li>
113+
<li>OcirPullSecret: ocirsecret</li>
114+
</ul>
115+
116+
## Run the pipeline
117+
118+
Pipeline runs automatically after commiting changes and when all of the above are properly set it should complete succesfully.
119+
120+
<p>
121+
<img src="azure-devops-oke.png" width="800" />
122+
123+
<p>
124+
Pipeline will create a Kubernetes <b><i>load balancer</i></b> service to provide a public access point to the pod in the OKE cluster:
125+
126+
<p>
127+
<PRE>
128+
kubectl get svc
129+
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
130+
httpd-lb LoadBalancer 10.96.175.74 144.200.51.195 80:32452/TCP 4h1m
131+
</PRE>
132+
133+
<p>
134+
Calling the LB endpoint with cURL or from the browser should show an echo:
135+
136+
<p>
137+
<PRE>
138+
curl 144.200.51.195
139+
{
140+
"path": "/",
141+
"headers": {
142+
"host": "144.200.51.195",
143+
"user-agent": "curl/8.4.0",
144+
"accept": "*/*"
145+
},
146+
"method": "GET",
147+
"body": "",
148+
"fresh": false,
149+
"hostname": "144.200.51.195",
150+
"ip": "::ffff:10.0.10.220",
151+
"ips": [],
152+
"protocol": "http",
153+
"query": {},
154+
"subdomains": [],
155+
"xhr": false,
156+
"os": {
157+
"hostname": "httpd-59d9987665-ltn8s"
158+
},
159+
"connection": {}
160+
}%
161+
</PRE>
162+
163+
### License
164+
165+
Copyright (c) 2024 Oracle and/or its affiliates.
166+
167+
Licensed under the Universal Permissive License (UPL), Version 1.0.
168+
169+
See [LICENSE](https://github.com/oracle-devrel/technology-engineering/blob/main/LICENSE) for more details.
1.01 MB
Loading
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
trigger:
2+
- main
3+
4+
pool:
5+
name: oci-vm
6+
7+
steps:
8+
- task: Docker@2
9+
displayName: 'Login to OCIR'
10+
inputs:
11+
command: login
12+
containerRegistry: '$(CONTAINER_REGISTRY)'
13+
- task: Docker@2
14+
displayName: 'Build & Push Container Image $(Build.BuildNumber)'
15+
inputs:
16+
command: buildAndPush
17+
buildContext: '$(System.DefaultWorkingDirectory)'
18+
Dockerfile: '$(System.DefaultWorkingDirectory)/Dockerfile'
19+
containerRegistry: '$(CONTAINER_REGISTRY)'
20+
repository: '$(CONTAINER_REPOSITORY)'
21+
tags: $(Build.BuildNumber)
22+
23+
- task: KubernetesManifest@0
24+
displayName: 'Setup secret'
25+
inputs:
26+
action: 'createSecret'
27+
secretType: 'dockerRegistry'
28+
secretName: '$(OcirPullSecret)'
29+
namespace: '$(K8S_NAMESPACE)'
30+
dockerRegistryEndpoint: '$(CONTAINER_REGISTRY)'
31+
kubernetesServiceConnection: '$(K8S_CONNECTION_NAME)'
32+
33+
- task: KubernetesManifest@0
34+
displayName: 'Deploy To K8s Cluster - test container'
35+
inputs:
36+
action: 'deploy'
37+
kubernetesServiceConnection: '$(K8S_CONNECTION_NAME)'
38+
namespace: '$(K8S_NAMESPACE)'
39+
manifests: |
40+
$(System.DefaultWorkingDirectory)/deployment.yaml
41+
$(System.DefaultWorkingDirectory)/svc.yaml
42+
imagePullSecrets: |
43+
$(OcirPullSecret)
44+
containers: |
45+
$(containerImageFullNameForK8sDeploy):$(Build.BuildNumber)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
apiVersion: v1
2+
kind: Secret
3+
metadata:
4+
name: oke-kubeconfig-azure-token
5+
namespace: kube-system
6+
annotations:
7+
kubernetes.io/service-account.name: azure
8+
type: kubernetes.io/service-account-token
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: httpd
5+
labels:
6+
app: httpd
7+
spec:
8+
replicas: 1
9+
selector:
10+
matchLabels:
11+
app: httpd
12+
template:
13+
metadata:
14+
labels:
15+
app: httpd
16+
spec:
17+
containers:
18+
- name: httpd
19+
image: fra.ocir.io/<TENANCY_NAMESPACE>/azure-test:1
20+
imagePullPolicy: Always
21+
ports:
22+
- containerPort: 8080
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: httpd-lb
5+
spec:
6+
selector:
7+
app: httpd
8+
ports:
9+
- port: 80
10+
targetPort: 8080
11+
type: LoadBalancer

0 commit comments

Comments
 (0)