├── .github └── workflows │ ├── deploy-to-azure-function.yml │ └── docker-build-scan.yml ├── .gitignore ├── 001-ELKMonitoring ├── .env ├── README.md ├── docker-compose.yaml └── images │ ├── 1.jpg │ └── 2.jpg ├── 002-JenkinsCICD ├── .gitlab-ci.yml ├── Dockerfile ├── Jenkinsfile ├── README.md ├── app.py ├── docker-compose.yml ├── github-workflow.yaml ├── images │ ├── github-personal-token.png │ └── jenkinspipeline.png ├── requirements.txt └── templates │ └── hello.html ├── 003-GitlabCICD ├── .gitlab-ci.yml ├── Dockerfile ├── README.md ├── app.py ├── docker-compose.yml ├── images │ ├── container-registry.png │ ├── gitlab-ci-pipeline.png │ ├── gitlab-runner.jpg │ ├── gitlab-url-token.png │ └── issue6-runner-is-not-ready-yet.png └── requirements.txt ├── 004-TerraformDockerDeployment ├── .gitignore ├── Dockerfile ├── README.md ├── app.py ├── config │ └── test │ │ ├── config.tfbackend │ │ └── test.tfvars ├── containers.tf ├── docker-compose.yaml ├── images.tf ├── images │ ├── gitlab-personal-accees-token.png │ └── hello-world.png ├── main.tf ├── output.tf ├── requirements.txt ├── run.sh └── variables.tf ├── 005-VaultJenkinsCICD ├── .env ├── .gitignore ├── Jenkinsfile ├── README.md ├── casc.yaml ├── docker-compose.yml ├── image │ └── README │ │ ├── 1672798209848.png │ │ └── 1672798247625.png ├── jenkinsplugin.Dockerfile ├── plugins.txt ├── vault-config.hcl └── vault.Dockerfile ├── 006-NexusJenkinsVagrantCICD ├── .env ├── .gitignore ├── Jenkinsfile ├── Jenkinsfile.bak ├── README.md ├── Vagrantfile ├── casc.yaml ├── docker-compose.yaml ├── images │ ├── helloworld.png │ ├── nexus-create-repo-2.png │ ├── nexus-create-repo.png │ ├── nexus-repo-configuration.png │ └── nexus-war-download-url.png ├── jenkinsplugin.Dockerfile ├── plugins.txt ├── pom.xml └── src │ └── main │ ├── java │ └── HelloWorld.java │ └── webapp │ └── WEB-INF │ └── web.xml ├── 007-VaultFreeIPAVagrantIAM ├── .env ├── .gitignore ├── README.md ├── Vagrantfile ├── docker-compose.yml ├── vault-config.hcl └── vault.Dockerfile ├── 008-AnsibleVagrantJenkinsDeployment ├── .gitignore ├── README.md ├── Vagrantfile ├── hosts.ini ├── install-jenkins-role.yml ├── install-jenkins.yml └── uninstall-jenkins.yml ├── 009-MinikubeHelmDeployment ├── README.md ├── images │ └── github_page.jpg └── values.yaml ├── 010-MinikubeGrafanaPrometheusMultipassMonitoring ├── README.md ├── components.yaml ├── images │ ├── alert-rules-1.png │ ├── chatgpg.png │ ├── grafana-query.png │ ├── prometheus-expression.png │ ├── slack.png │ ├── template-id.png │ ├── template-import.png │ └── top-5-memory-intense-pod.png ├── pod-health-status.json ├── values.prometheus-only.yaml ├── values.yaml └── vm-health-status.json ├── 011-KinDKubeconfigRBACConfiguration ├── README.md └── readonly-manifest.yaml ├── 012-CronjobVaultBackupHelmMinikube ├── .gitignore ├── README.md ├── helm-chart │ ├── Chart.yaml │ └── templates │ │ ├── _helpers.tpl │ │ └── cronjob.yaml ├── images │ ├── minio-bucket.png │ └── minio-console.png ├── upload.sh ├── vault-backup-values.yaml └── vault-values.yaml ├── 013-JavaMonitoryConfigmapMinikube ├── Dockerfile ├── README.md ├── archive │ ├── FielMonitorWithBreak.java │ ├── configmap2.yaml │ ├── file-monitor-1.0.0.jar │ ├── pod.yaml │ ├── pod2.yaml │ ├── pod3.yaml │ └── src-readfile │ │ └── main │ │ └── java │ │ └── FileMonitor.java ├── configmap.yaml ├── images │ └── github-package.png ├── pod.yaml ├── pom.xml └── src │ └── main │ └── java │ └── FileMonitor.java ├── 014-VaultInjectorMinikube ├── README.md ├── app-deployment.yaml ├── patch-app-deployment.yaml └── values.yaml ├── 015-GitRemoveLargeFile └── README.md ├── 016-AzureFunctionTerraform ├── README.md ├── app │ ├── ChanceNPMProject │ │ ├── .funcignore │ │ ├── .gitignore │ │ ├── ChanceNodeHttpTrigger │ │ │ ├── function.json │ │ │ └── index.js │ │ ├── host.json │ │ └── package.json │ ├── ChancePythonProject │ │ ├── .funcignore │ │ ├── .gitignore │ │ ├── ChancePythonHttpTrigger │ │ │ ├── __init__.py │ │ │ └── function.json │ │ ├── getting_started.md │ │ ├── host.json │ │ └── requirements.txt │ └── ChancePythonProject2 │ │ ├── .gitignore │ │ ├── app.py │ │ ├── getting_started.md │ │ ├── host.json │ │ ├── requirements.txt │ │ └── templates │ │ └── index.html ├── function-apps │ ├── archives │ │ └── dev │ │ │ ├── datafactory.tf │ │ │ ├── function-apps.tf │ │ │ ├── main.auto.tfvars │ │ │ ├── main.tf │ │ │ ├── naming_standards.tf │ │ │ ├── outputs.tf │ │ │ ├── storage-account.tf │ │ │ ├── terraform.tf │ │ │ └── variable.tf │ ├── backend_modules │ │ ├── function-apps │ │ │ ├── function-apps.tf │ │ │ └── variables.tf │ │ ├── resource-group │ │ │ ├── resource-group.tf │ │ │ └── variables.tf │ │ └── storage-account │ │ │ ├── locals.tf │ │ │ ├── main.tf │ │ │ └── variables.tf │ ├── dev-working │ │ ├── datafactory.tf │ │ ├── function-apps.tf │ │ ├── main.auto.tfvars │ │ ├── main.tf │ │ ├── naming_standards.tf │ │ ├── outputs.tf │ │ ├── storage_accounts.tf │ │ ├── terraform.tf │ │ └── variable.tf │ ├── modules │ │ └── dev │ │ │ ├── datafactory.tf │ │ │ ├── function-apps.tf │ │ │ ├── naming_standards.tf │ │ │ ├── rg.tf │ │ │ ├── storage-account.tf │ │ │ └── variable.tf │ ├── naming_standards.tf │ └── variable.tf └── variables.tf ├── 017-AzureLogicalAppTerraform ├── 20231005-Project-AzureKeyVaultSecretExpirySolution.md ├── README.md ├── images │ └── azure-keyvault-secretexpirysolution.jpg └── terraform │ ├── backend_modules │ ├── app-service-plan │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── logic-app-standard │ │ ├── app_service_plan.tf │ │ ├── main.tf │ │ └── variables.tf │ ├── resource-group │ │ ├── resource-group.tf │ │ └── variables.tf │ └── storage-account │ │ ├── locals.tf │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── dev │ ├── app-service-plan.tf │ ├── logic-app-standard.tf │ ├── main.auto.tfvars │ ├── main.tf │ ├── naming_standards.tf │ ├── outputs.tf │ ├── storage_accounts.tf │ ├── terraform.tf │ └── variable.tf │ ├── modules │ └── dev │ │ ├── app-service-plan.tf │ │ ├── logic-app-standard.tf │ │ ├── naming_standards.tf │ │ ├── output.tf │ │ ├── rg.tf │ │ ├── storage-account.tf │ │ └── variable.tf │ ├── naming_standards.tf │ └── variable.tf ├── 018-AzureDevOpsJavaWebAppCICD ├── CHANGELOG.md ├── helloworld │ ├── Jenkinsfile │ ├── README.md │ ├── archive │ │ ├── Dockerfile │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── devopschance │ │ │ └── helloworld │ │ │ └── HelloWorld.java │ ├── images │ │ ├── primeafces-in-out-button.png │ │ ├── primeafces-layout.png │ │ ├── primefaces-datatable.png │ │ ├── primefaces-todo-list-v2.png │ │ └── primefaces-todo-list.png │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── microsoft │ │ │ └── azure │ │ │ └── samples │ │ │ ├── controller │ │ │ └── TodoListController.java │ │ │ ├── dao │ │ │ ├── ItemManagement.java │ │ │ └── TodoItemManagementInMemory.java │ │ │ └── model │ │ │ └── TodoItem.java │ │ └── webapp │ │ ├── META-INF │ │ └── context.xml │ │ ├── WEB-INF │ │ ├── beans.xml │ │ ├── classes │ │ │ └── logging.properties │ │ ├── faces-config.xml │ │ └── web.xml │ │ └── index.xhtml └── java-cicd-v0.0.1.yaml ├── 019-TerraformAzureDevOpsWorkflow ├── CHANGELOG.md ├── azuredevops-pipeline.yaml └── dev │ └── dev01 │ └── ce │ └── test.tf ├── 020-GithubActionJavaDockerfileCI ├── Dockerfile ├── README.md ├── docker-build-scan.yml ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── example │ └── CurrentTimeServer.java ├── 021-GithubActionDockerImageFunctionCD ├── README.md └── deploy-to-azure-function.yml ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── HelmOracleCloudK8s └── README.md ├── README.md ├── README.md.template ├── TerraformOracleCloudVM ├── README.md └── tf-provider │ ├── .terraform.lock.hcl │ ├── README.md │ ├── availability-domains.tf │ ├── compute.tf │ ├── config │ └── dev.tfvars │ ├── network.tf │ ├── output.tf │ ├── provider.tf │ └── variables.tf ├── aks ├── aks-upgrade │ └── README.md └── backup-solution-velero │ └── README.md ├── archive └── 018-AzureDevOpsFunctionRelease │ ├── 20231005-Project-AzureKeyVaultSecretExpirySolution.md │ ├── README.md │ └── single_pipeline │ ├── aks-build-deploy.yaml │ └── function-build-deploy.yaml ├── cloud └── azure │ ├── 20230614-AzureLearningPlan.md │ ├── 20230616-IAM-Tenant.md │ ├── 20230628-IAM-AAD.md │ ├── 20230629-IAM-RBAC.md │ ├── 20230706-IAM-ManagedIdentity.md │ ├── 20230712-IAM-PIM.md │ ├── 20230717-IAM-Intune.md │ ├── 20230718-ARM-ResourceManagement.md │ ├── 20230720-Compute-VM.md │ ├── 20230721-Compute-AzureBastion.md │ ├── 20230724-Compute-AKS.md │ ├── 20230726-Compute-ACI.md │ ├── 20230727-Compute-ACR.md │ ├── 20230728-Compute-AppService.md │ ├── 20230729-Compute-AppServicePlan.md │ ├── 20230731-Compute-AzureServiceFabric.md │ ├── 20230801-Compute-AzureStaticWebApp.md │ ├── 20230802-Compute-AzureSpringApps.md │ ├── 20230803-Compute-AzureFunctions.md │ ├── 20230821-Compute-AzureLogicApp.md │ ├── 20230822-Compute-AzureBatch.md │ ├── 20230824-Compute-AzureVMwareSolution.md │ ├── 20230830-Compute-AzureSpotVM.md │ ├── 20230904-Network-AzureVirtualNetwork.md │ ├── 20230906-Network-IP.md │ ├── 20230908-Network-DNS.md │ ├── 20230911-Network-TCP.md │ ├── 20230912-Network-OSI.md │ ├── 20230915-Network-NetworkSecurityGroup.md │ └── README.md ├── docs ├── index.yaml ├── meeting_checkout.md └── test-service-0.1.0.tgz ├── helm-charts └── test-service │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── hpa.yaml │ ├── ingress.yaml │ ├── service.yaml │ ├── serviceaccount.yaml │ └── tests │ │ └── test-connection.yaml │ └── values.yaml ├── k8s-onbarding ├── README.md ├── archive │ └── k8s-onboarding.md └── images │ ├── k9s.png │ └── vscode.png ├── keycloak-integration ├── freeipa │ ├── .env │ ├── README.md │ ├── docker-compose.yaml │ └── images │ │ ├── group-mapper.png │ │ └── ldap.png └── keycloak-upgrade │ ├── README.md │ ├── values-keycloak-16.yaml │ ├── values-keycloak-20.yaml │ └── values-postgres-15-for-keycloak-20.yaml ├── linux ├── 001-ls.md ├── 002-cd.md ├── 003-pwd.md ├── 004-mkdir.md ├── 005-rmdir.md ├── 006-cat.md ├── 007-nl.md ├── 008-more.md ├── 009-less.md └── README.md ├── python ├── practice-together │ ├── 001-introduction │ │ └── README.md │ ├── 002-simpleArraySum │ │ ├── README.md │ │ ├── simpleArraySum.py │ │ └── simpleArraySum_2.py │ ├── 003-compareTriplets │ │ ├── README.md │ │ └── compareTriplets.py │ ├── 004-diagonalDifference │ │ └── diagonalDifference.py │ ├── 005-plusMinus │ │ └── plusMinus.py │ ├── 006-staircase │ │ └── staircase.py │ ├── 007-miniMaxSum │ │ ├── miniMaxSum.py │ │ └── miniMaxSum2.py │ ├── 008-birthdayCakeCandles │ │ ├── birthdayCakeCandles.py │ │ └── birthdayCakeCandles2.py │ ├── 009-timeConversion │ │ └── timeConversion.py │ ├── 010- gradingStudents │ │ └── gradingStudents.py │ ├── 011-kangaroo │ │ └── kangaroo.py │ ├── 012-breakingRecords │ │ └── breakingRecords.py │ ├── 013-betweenTwoSets │ │ └── betweenTwoSets.py │ ├── 014-ArrayDS │ │ └── reverseArray.py │ ├── 015-2ArrayDS │ │ └── hourglassSum.py │ ├── 016-LeftRotation │ │ └── rotateLeft.py │ ├── 017-PrintTheElementsOfALinkedList │ │ └── printLinkedList.py │ ├── 018-InsertANodeAtTheHeadOfALinkedList │ │ └── insertNodeAtHead.py │ └── 019-InsertANodeAtTheTailOfALinkedList copy │ │ └── insertNodeAtTail.py └── study-together │ ├── 001-introduction │ ├── README.md │ └── practice │ │ └── README.md │ ├── 002-reference │ ├── README.md │ └── practice │ │ └── README.md │ ├── 003-history │ ├── README.md │ └── practice │ │ └── README.md │ ├── 004-installation │ ├── README.md │ └── practice │ │ └── README.md │ ├── 005-inputoutput │ ├── README.md │ └── practice │ │ └── README.md │ ├── 006-variables │ ├── README.md │ └── practice │ │ └── README.md │ ├── 007-basic │ ├── README.md │ └── practice │ │ └── README.md │ ├── 008-number1 │ ├── README.md │ └── practice │ │ └── README.md │ ├── 009-number2 │ ├── README.md │ └── practice │ │ └── README.md │ ├── 010-number3 │ ├── README.md │ └── practice │ │ └── README.md │ ├── 011-string1 │ ├── README.md │ └── practice │ │ └── README.md │ ├── 012-string2 │ ├── README.md │ └── practice │ │ └── README.md │ ├── 013-string3 │ ├── README.md │ └── practice │ │ ├── README.md │ │ └── chance-1.py │ ├── 014-sequence1 │ └── README.md │ ├── 015-sequence2 │ └── README.md │ ├── 016-list1 │ └── README.md │ ├── 017-list2 │ └── README.md │ ├── 018-tuple │ └── README.md │ ├── 019-set │ └── README.md │ ├── 020-dict │ └── README.md │ ├── 021-if │ └── README.md │ ├── 022-for │ └── README.md │ ├── 023-while │ └── README.md │ ├── 024-function1 │ └── README.md │ ├── 025-function2 │ └── README.md │ ├── 026-function3 │ └── README.md │ ├── 027-function4 │ └── README.md │ ├── 028-fileOperation │ └── README.md │ ├── 029-exception │ └── README.md │ └── README.md ├── script.sh.template ├── study-diary └── 2023 │ ├── 07 │ ├── 20230711 │ ├── 20230712.md │ ├── 20230713.md │ ├── 20230714.md │ ├── 20230717.md │ ├── 20230718.md │ ├── 20230719.md │ ├── 20230720.md │ ├── 20230721.md │ ├── 20230724.md │ ├── 20230726.md │ ├── 20230727.md │ ├── 20230728.md │ └── 20230731.md │ ├── 08 │ ├── 20230801.md │ ├── 20230802.md │ ├── 20230803.md │ ├── 20230804.md │ ├── 20230821.md │ ├── 20230822.md │ ├── 20230824.md │ ├── 20230825.md │ ├── 20230830.md │ └── 20230831.md │ └── 09 │ ├── 20230907.md │ ├── 20230910.md │ ├── 20230912.md │ └── 20230914.md └── tmp └── keyvault-issue.png /.github/workflows/deploy-to-azure-function.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Docker Image to Azure Function 2 | 3 | on: 4 | push: 5 | paths: 6 | - '021-GithubActionDockerImageFunctionCD/**' 7 | workflow_dispatch: # Allows manual triggering of the workflow 8 | 9 | permissions: 10 | id-token: write 11 | contents: read 12 | 13 | jobs: 14 | deploy: 15 | name: Deploy to Azure Function 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | # Step 1: Log in to Azure 20 | - name: Log in to Azure 21 | uses: azure/login@v2 22 | with: 23 | client-id: ${{ secrets.AZURE_CLIENT_ID }} 24 | tenant-id: ${{ secrets.AZURE_TENANT_ID }} 25 | subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} 26 | 27 | # Step 2: Deploy the Docker image to Azure Function 28 | - name: Deploy to Azure Function 29 | run: | 30 | az functionapp config container set \ 31 | --name ${{ vars.FUNCTION_APP_NAME }} \ 32 | --resource-group ${{ vars.RESOURCE_GROUP_NAME }} \ 33 | --docker-custom-image-name ${{ vars.IMAGE_NAME }}:${{ vars.IMAGE_TAG }} -------------------------------------------------------------------------------- /.github/workflows/docker-build-scan.yml: -------------------------------------------------------------------------------- 1 | name: Build, Scan, and Push Docker Image with Commit Hash 2 | 3 | on: 4 | push: 5 | paths: 6 | - '020-GithubActionJavaDockerfileCI/**' 7 | workflow_dispatch: 8 | 9 | jobs: 10 | build-and-scan: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | # Step 1: Check out the code 15 | - name: Checkout code 16 | uses: actions/checkout@v3 17 | 18 | # Step 2: Set up Docker 19 | - name: Set up Docker 20 | uses: docker/setup-buildx-action@v2 21 | 22 | # Step 3: Get Git commit hash 23 | - name: Get Git commit hash 24 | id: vars 25 | run: echo "GIT_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV 26 | 27 | # Step 4: Build Docker image with commit hash 28 | - name: Build Docker image 29 | run: | 30 | docker build -t ghcr.io/${{ github.repository_owner }}/current-time-app:${{ env.GIT_COMMIT }} ./020-GithubActionJavaDockerfileCI 31 | 32 | # Step 5: Log in to GitHub Container Registry 33 | - name: Log in to GitHub Container Registry 34 | uses: docker/login-action@v2 35 | with: 36 | registry: ghcr.io 37 | username: ${{ github.actor }} 38 | password: ${{ secrets.YOUR_GITHUB_TOKEN }} 39 | 40 | # Step 6: Push Docker image to GHCR 41 | - name: Push Docker image 42 | run: | 43 | docker push ghcr.io/${{ github.repository_owner }}/current-time-app:${{ env.GIT_COMMIT }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .terraform 3 | .terraform* 4 | terraform.tfstate* 5 | .venv* 6 | .vscode* 7 | 8 | 9 | -------------------------------------------------------------------------------- /001-ELKMonitoring/.env: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Password for the 'elastic' user (at least 6 characters) 4 | ELASTIC_PASSWORD= 5 | 6 | # Password for the 'kibana_system' user (at least 6 characters) 7 | KIBANA_PASSWORD= 8 | 9 | # Version of Elastic products 10 | STACK_VERSION=8.5.0 11 | 12 | # Set the cluster name 13 | CLUSTER_NAME=docker-cluster 14 | 15 | # Set to 'basic' or 'trial' to automatically start the 30-day trial 16 | LICENSE=basic 17 | #LICENSE=trial 18 | 19 | # Port to expose Elasticsearch HTTP API to the host 20 | ES_PORT=9200 21 | #ES_PORT=127.0.0.1:9200 22 | 23 | # Port to expose Kibana to the host 24 | KIBANA_PORT=5601 25 | #KIBANA_PORT=80 26 | 27 | # Increase or decrease based on the available host memory (in bytes) 28 | MEM_LIMIT=1073741824 29 | 30 | # Project namespace (defaults to the current folder name if not set) 31 | #COMPOSE_PROJECT_NAME=myproject 32 | 33 | -------------------------------------------------------------------------------- /001-ELKMonitoring/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/001-ELKMonitoring/images/1.jpg -------------------------------------------------------------------------------- /001-ELKMonitoring/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/001-ELKMonitoring/images/2.jpg -------------------------------------------------------------------------------- /002-JenkinsCICD/.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | build-job: 2 | stage: trigger jenkins cicd 3 | script: 4 | - curl -X POST --user JENKINS_USER:JENKINS_TOKEN http://0.0.0.0:80/job/hello-world/build 5 | 6 | 7 | -------------------------------------------------------------------------------- /002-JenkinsCICD/Dockerfile: -------------------------------------------------------------------------------- 1 | # docker run -p 8080:8080 --name color-web color-web:init 2 | FROM python:3.8-alpine 3 | 4 | RUN mkdir /app 5 | 6 | COPY . /app 7 | 8 | WORKDIR /app 9 | 10 | RUN pip install -r requirements.txt 11 | 12 | EXPOSE 8080 13 | 14 | CMD ["python", "app.py"] 15 | -------------------------------------------------------------------------------- /002-JenkinsCICD/Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent any 3 | environment{ 4 | registryUrlBase = "https://ghcr.io" 5 | registryUrl = "ghcr.io/chance2021/devopsdaydayup" 6 | registryCredentialsId = 'github-token' 7 | commitID = sh(script: 'git rev-parse --short HEAD', returnStdout:true).trim() 8 | containerName = "color-web" 9 | } 10 | stages { 11 | stage('Build and Push Image') { 12 | steps { 13 | // 14 | sh"whoami" 15 | script { 16 | docker.withRegistry(registryUrlBase, registryCredentialsId) { 17 | dockerImage = docker.build("$registryUrl:$commitID","./002-JenkinsCICD") 18 | dockerImage.push() 19 | } 20 | } 21 | } 22 | } 23 | stage('Deploy') { 24 | steps { 25 | sh "docker stop $containerName" 26 | sh "docker rm $containerName" 27 | sh "docker run -d -p 8080:8080 --name $containerName $registryUrl:$commitID" 28 | } 29 | } 30 | stage('Clean Up') { 31 | steps { 32 | sh "docker rmi --force $registryUrl:$commitID" 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /002-JenkinsCICD/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | 4 | @app.route("/") 5 | def hello(): 6 | return "Hello World!" 7 | 8 | if __name__ == "__main__": 9 | app.run(host='0.0.0.0', port=8080) 10 | -------------------------------------------------------------------------------- /002-JenkinsCICD/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | jenkins: 5 | image: docker.io/bitnami/jenkins:2 6 | user: root 7 | ports: 8 | - '80:8080' 9 | environment: 10 | - JENKINS_PASSWORD=bitnami 11 | - JENKINS_USERNAME=user 12 | - JENKINS_USER=root 13 | - TZ=America/Toronto 14 | volumes: 15 | - 'jenkins_data:/bitnami/jenkins' 16 | - '/usr/bin/docker:/usr/bin/docker' 17 | - '/var/run/docker.sock:/var/run/docker.sock' 18 | 19 | volumes: 20 | jenkins_data: 21 | driver: local 22 | 23 | -------------------------------------------------------------------------------- /002-JenkinsCICD/github-workflow.yaml: -------------------------------------------------------------------------------- 1 | #name: CICD 2 | #run-name: ${{ github.actor }} is running CICD 3 | #on: [push] 4 | #jobs: 5 | # trigger-jenkins-cicd: 6 | # runs-on: ubuntu-latest 7 | # steps: 8 | # - run: curl -X POST --user JENKINS_USER:JENKINS_TOKEN http://0.0.0.0:80/job/hello-world/build 9 | -------------------------------------------------------------------------------- /002-JenkinsCICD/images/github-personal-token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/002-JenkinsCICD/images/github-personal-token.png -------------------------------------------------------------------------------- /002-JenkinsCICD/images/jenkinspipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/002-JenkinsCICD/images/jenkinspipeline.png -------------------------------------------------------------------------------- /002-JenkinsCICD/requirements.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | -------------------------------------------------------------------------------- /002-JenkinsCICD/templates/hello.html: -------------------------------------------------------------------------------- 1 | 2 | Hello from Flask 3 | 4 |
8 | {% if name %} 9 |

Hello from {{ name }}!

10 | {% else %} 11 |

Hello, World!

12 | {% endif %} 13 | 14 | {% if contents %} 15 | 18 | {% endif %} 19 | 20 |
21 | -------------------------------------------------------------------------------- /003-GitlabCICD/.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | cicd: 2 | # Use the official docker image. 3 | image: docker:latest 4 | stage: build 5 | tags: 6 | - test 7 | services: 8 | - docker:dind 9 | before_script: 10 | - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY 11 | # Default branch leaves tag empty (= latest tag) 12 | # All other branches are tagged with the escaped branch name (commit ref slug) 13 | script: 14 | - | 15 | export tag=":$CI_COMMIT_SHORT_SHA" 16 | echo "testing..." 17 | echo "Running on branch '$CI_COMMIT_BRANCH': tag = $tag" 18 | - docker build --pull -t "$CI_REGISTRY_IMAGE${tag}" . 19 | - docker push "$CI_REGISTRY_IMAGE${tag}" 20 | - docker rmi "$CI_REGISTRY_IMAGE${tag}" 21 | - docker rm -f $(docker ps -f name=hello-world -q) 22 | - docker run -d -p 8080:8080 --name hello-world "$CI_REGISTRY_IMAGE${tag}" 23 | # Run this job in a branch where a Dockerfile exists 24 | rules: 25 | - if: $CI_COMMIT_BRANCH 26 | exists: 27 | - Dockerfile 28 | 29 | -------------------------------------------------------------------------------- /003-GitlabCICD/Dockerfile: -------------------------------------------------------------------------------- 1 | # docker run -p 8080:8080 --name color-web ghcr.io/chance2021/devopsdaydayup:colorweb 2 | FROM python:3.8-alpine 3 | 4 | RUN mkdir /app 5 | 6 | COPY . /app 7 | 8 | WORKDIR /app 9 | 10 | RUN pip install -r requirements.txt 11 | 12 | EXPOSE 8080 13 | 14 | CMD ["python", "app.py"] 15 | -------------------------------------------------------------------------------- /003-GitlabCICD/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | 4 | @app.route("/") 5 | def hello(): 6 | return "Hello World!" 7 | 8 | if __name__ == "__main__": 9 | app.run(host='0.0.0.0', port=8080) 10 | -------------------------------------------------------------------------------- /003-GitlabCICD/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.6' 2 | services: 3 | web: 4 | image: 'gitlab/gitlab-ce:latest' 5 | restart: always 6 | hostname: 'gitlab.chance20221020.com' 7 | environment: 8 | GITLAB_ROOT_PASSWORD: "changeme" 9 | GITLAB_OMNIBUS_CONFIG: | 10 | external_url 'https://gitlab.chance20221020.com' 11 | # Add any other gitlab.rb configuration here, each on its own line 12 | ports: 13 | - '80:80' 14 | - '443:443' 15 | - '8822:22' 16 | - '5005:5005' 17 | volumes: 18 | - 'gitlab_config:/etc/gitlab' 19 | - 'gitlab_log:/var/log/gitlab' 20 | - 'gitlab_data:/var/opt/gitlab' 21 | shm_size: '256m' 22 | hello-world: 23 | image: ghcr.io/chance2021/devopsdaydayup:colorweb 24 | ports: 25 | - 8080:8080 26 | gitlab-runner: 27 | image: 'gitlab/gitlab-runner:latest' 28 | restart: always 29 | user: root 30 | volumes: 31 | - 'gitlab_runner_config:/etc/gitlab-runner' 32 | - '/var/run/docker.sock:/var/run/docker.sock' 33 | - '/usr/bin/docker:/usr/bin/docker' 34 | - '/etc/hosts:/etc/hosts' 35 | volumes: 36 | gitlab_data: 37 | driver: local 38 | gitlab_log: 39 | driver: local 40 | gitlab_config: 41 | driver: local 42 | gitlab_runner_config: 43 | driver: local 44 | -------------------------------------------------------------------------------- /003-GitlabCICD/images/container-registry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/003-GitlabCICD/images/container-registry.png -------------------------------------------------------------------------------- /003-GitlabCICD/images/gitlab-ci-pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/003-GitlabCICD/images/gitlab-ci-pipeline.png -------------------------------------------------------------------------------- /003-GitlabCICD/images/gitlab-runner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/003-GitlabCICD/images/gitlab-runner.jpg -------------------------------------------------------------------------------- /003-GitlabCICD/images/gitlab-url-token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/003-GitlabCICD/images/gitlab-url-token.png -------------------------------------------------------------------------------- /003-GitlabCICD/images/issue6-runner-is-not-ready-yet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/003-GitlabCICD/images/issue6-runner-is-not-ready-yet.png -------------------------------------------------------------------------------- /003-GitlabCICD/requirements.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | -------------------------------------------------------------------------------- /004-TerraformDockerDeployment/.gitignore: -------------------------------------------------------------------------------- 1 | .terraform* 2 | terraform.tfstate 3 | deploy.tfplan 4 | .env 5 | -------------------------------------------------------------------------------- /004-TerraformDockerDeployment/Dockerfile: -------------------------------------------------------------------------------- 1 | # docker run -p 8080:8080 --name hello-world hello-world:develop 2 | FROM python:3.8-alpine 3 | 4 | RUN mkdir /app 5 | 6 | COPY . /app 7 | 8 | WORKDIR /app 9 | 10 | RUN pip install -r requirements.txt 11 | 12 | EXPOSE 8080 13 | 14 | CMD ["python", "app.py"] 15 | 16 | -------------------------------------------------------------------------------- /004-TerraformDockerDeployment/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | 4 | @app.route("/") 5 | def hello(): 6 | return "Hello World!" 7 | 8 | if __name__ == "__main__": 9 | app.run(host='0.0.0.0', port=8080) 10 | -------------------------------------------------------------------------------- /004-TerraformDockerDeployment/config/test/config.tfbackend: -------------------------------------------------------------------------------- 1 | # export PROJECT_ID="" 2 | # export TF_USERNAME="" 3 | # export TF_PASSWORD="" 4 | # export TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/old-state-name" 5 | # Note: Please replace above variables into below 6 | # --- 7 | #address=${TF_ADDRESS} 8 | #lock_address=${TF_ADDRESS}/lock 9 | #unlock_address=${TF_ADDRESS}/lock 10 | #username=${TF_USERNAME} 11 | #password=${TF_PASSWORD} 12 | #lock_method=POST 13 | #unlock_method=DELETE 14 | #retry_wait_min=5 15 | 16 | address="https://gitlab.example20221106.com/api/v4/projects/34/terraform/state/old-state-name" 17 | lock_address="https://gitlab.example20221106.com/api/v4/projects/34/terraform/state/old-state-name/lock" 18 | unlock_address="https://gitlab.example20221106.com/api/v4/projects/34/terraform/state/old-state-name/lock" 19 | username="root" 20 | password=" hello_world.txt' 22 | sh 'echo $testing >> hello_world.txt' 23 | sh 'cat hello_world.txt' 24 | sh 'echo $testing_again|tee testing_again.txt' 25 | sh 'cat testing_again.txt' 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /005-VaultJenkinsCICD/casc.yaml: -------------------------------------------------------------------------------- 1 | unclassified: 2 | location: 3 | # You can retrieve the ip by `ip addr show docker0` in `inet` line. 4 | url: http://172.17.0.1:8080/ 5 | jenkins: 6 | securityRealm: 7 | local: 8 | allowsSignup: false 9 | users: 10 | - id: ${JENKINS_ADMIN_ID} 11 | password: ${JENKINS_ADMIN_PASSWORD} 12 | authorizationStrategy: 13 | globalMatrix: 14 | permissions: 15 | - "Overall/Administer:admin" 16 | - "Overall/Read:authenticated" 17 | remotingSecurity: 18 | enabled: true 19 | security: 20 | queueItemAuthenticator: 21 | authenticators: 22 | - global: 23 | strategy: triggeringUsersAuthorizationStrategy 24 | -------------------------------------------------------------------------------- /005-VaultJenkinsCICD/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | jenkins: 4 | build: 5 | context: . 6 | dockerfile: jenkinsplugin.Dockerfile 7 | user: root 8 | privileged: true 9 | ports: 10 | - '8080:8080' 11 | - '50000:50000' 12 | environment: 13 | # Please update JENKINS_PASSWORD and JENKINS_USERNAME in .env file 14 | - JENKINS_USER=root 15 | - TZ=America/Toronto 16 | - JENKINS_ADMIN_ID=$JENKINS_USERNAME 17 | - JENKINS_ADMIN_PASSWORD=$JENKINS_PASSWORD 18 | volumes: 19 | - 'jenkins_data:/var/jenkins_home' 20 | - '/usr/bin/docker:/usr/bin/docker' 21 | - '/var/run/docker.sock:/var/run/docker.sock' 22 | vault: 23 | build: 24 | context: . 25 | dockerfile: vault.Dockerfile 26 | cap_add: 27 | - IPC_LOCK 28 | ports: 29 | - '8200:8200' 30 | volumes: 31 | - type: volume 32 | source: vault_file 33 | target: /vault/file 34 | - type: volume 35 | source: vault_config 36 | target: /vault/config 37 | 38 | 39 | volumes: 40 | jenkins_data: 41 | driver: local 42 | vault_file: 43 | driver: local 44 | vault_config: 45 | driver: local 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /005-VaultJenkinsCICD/image/README/1672798209848.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/005-VaultJenkinsCICD/image/README/1672798209848.png -------------------------------------------------------------------------------- /005-VaultJenkinsCICD/image/README/1672798247625.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/005-VaultJenkinsCICD/image/README/1672798247625.png -------------------------------------------------------------------------------- /005-VaultJenkinsCICD/jenkinsplugin.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jenkins/jenkins:jdk11 2 | ENV JAVA_OPTS -Djenkins.install.runSetupWizard=false 3 | ENV CASC_JENKINS_CONFIG /var/jenkins_config/casc.yaml 4 | COPY plugins.txt /usr/share/jenkins/ref/plugins.txt 5 | RUN jenkins-plugin-cli --plugin-file /usr/share/jenkins/ref/plugins.txt 6 | COPY casc.yaml /var/jenkins_config/casc.yaml 7 | 8 | -------------------------------------------------------------------------------- /005-VaultJenkinsCICD/plugins.txt: -------------------------------------------------------------------------------- 1 | credentials:1214.v1de940103927 2 | configuration-as-code:1569.vb_72405b_80249 3 | docker-workflow:528.v7c193a_0b_e67c 4 | job-dsl:1.81 5 | git:4.12.1 6 | github:1.36.0 7 | authorize-project:1.4.0 8 | matrix-auth:3.1.5 9 | job-restrictions:0.8 10 | view-job-filters:2.3 11 | nested-view:1.26 12 | # build-pipeline-plugin: The Jenkins project announced an unresolved security vulnerability affecting the current version of this plugin 13 | build-pipeline-plugin:1.5.7.1 14 | hashicorp-vault-plugin:359.v2da_3b_45f17d5 15 | 16 | -------------------------------------------------------------------------------- /005-VaultJenkinsCICD/vault-config.hcl: -------------------------------------------------------------------------------- 1 | storage "raft" { 2 | path = "/vault/data" 3 | node_id = "node1" 4 | } 5 | 6 | listener "tcp" { 7 | address = "0.0.0.0:8200" 8 | tls_disable = "true" 9 | #tls_cert_file = "/vault/vault.crt" 10 | #tls_key_file = "/vault/vault.key" 11 | #tls_client_ca_file = "/vault/vault.ca" 12 | } 13 | 14 | api_addr = "http://127.0.0.1:8200" 15 | cluster_addr = "https://127.0.0.1:8201" 16 | ui = true 17 | disable_mlock = true 18 | max_lease_ttl = "8784h" 19 | default_lease_ttl = "8784h" 20 | 21 | -------------------------------------------------------------------------------- /005-VaultJenkinsCICD/vault.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM vault:1.12.1 2 | WORKDIR /vault/data 3 | COPY vault-config.hcl /vault/config/vault-config.hcl 4 | CMD vault server -config=/vault/config/vault-config.hcl 5 | -------------------------------------------------------------------------------- /006-NexusJenkinsVagrantCICD/.env: -------------------------------------------------------------------------------- 1 | JENKINS_PASSWORD=bitnami 2 | JENKINS_USERNAME=admin 3 | -------------------------------------------------------------------------------- /006-NexusJenkinsVagrantCICD/.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant* 2 | -------------------------------------------------------------------------------- /006-NexusJenkinsVagrantCICD/casc.yaml: -------------------------------------------------------------------------------- 1 | unclassified: 2 | location: 3 | # You can retrieve the ip by `ip addr show docker0` in `inet` line. 4 | url: http://172.17.0.1:8080/ 5 | jenkins: 6 | securityRealm: 7 | local: 8 | allowsSignup: false 9 | users: 10 | - id: ${JENKINS_ADMIN_ID} 11 | password: ${JENKINS_ADMIN_PASSWORD} 12 | authorizationStrategy: 13 | globalMatrix: 14 | permissions: 15 | - "Overall/Administer:admin" 16 | - "Overall/Read:authenticated" 17 | remotingSecurity: 18 | enabled: true 19 | security: 20 | queueItemAuthenticator: 21 | authenticators: 22 | - global: 23 | strategy: triggeringUsersAuthorizationStrategy 24 | -------------------------------------------------------------------------------- /006-NexusJenkinsVagrantCICD/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | 3 | services: 4 | nexus: 5 | image: sonatype/nexus3 6 | volumes: 7 | - "nexus-data:/nexus-data" 8 | ports: 9 | - "8081:8081" 10 | jenkins: 11 | build: 12 | context: . 13 | dockerfile: jenkinsplugin.Dockerfile 14 | user: root 15 | privileged: true 16 | ports: 17 | - '8080:8080' 18 | - '50000:50000' 19 | environment: 20 | # Please update JENKINS_PASSWORD and JENKINS_USERNAME in .env file 21 | - JENKINS_USER=root 22 | - TZ=America/Toronto 23 | - JENKINS_ADMIN_ID=$JENKINS_USERNAME 24 | - JENKINS_ADMIN_PASSWORD=$JENKINS_PASSWORD 25 | volumes: 26 | - 'jenkins_data:/var/jenkins_home' 27 | - '/usr/bin/docker:/usr/bin/docker' 28 | - '/var/run/docker.sock:/var/run/docker.sock' 29 | 30 | volumes: 31 | nexus-data: 32 | driver: local 33 | jenkins_data: 34 | driver: local 35 | 36 | 37 | -------------------------------------------------------------------------------- /006-NexusJenkinsVagrantCICD/images/helloworld.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/006-NexusJenkinsVagrantCICD/images/helloworld.png -------------------------------------------------------------------------------- /006-NexusJenkinsVagrantCICD/images/nexus-create-repo-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/006-NexusJenkinsVagrantCICD/images/nexus-create-repo-2.png -------------------------------------------------------------------------------- /006-NexusJenkinsVagrantCICD/images/nexus-create-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/006-NexusJenkinsVagrantCICD/images/nexus-create-repo.png -------------------------------------------------------------------------------- /006-NexusJenkinsVagrantCICD/images/nexus-repo-configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/006-NexusJenkinsVagrantCICD/images/nexus-repo-configuration.png -------------------------------------------------------------------------------- /006-NexusJenkinsVagrantCICD/images/nexus-war-download-url.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/006-NexusJenkinsVagrantCICD/images/nexus-war-download-url.png -------------------------------------------------------------------------------- /006-NexusJenkinsVagrantCICD/jenkinsplugin.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jenkins/jenkins:jdk11 2 | ENV JAVA_OPTS -Djenkins.install.runSetupWizard=false 3 | ENV CASC_JENKINS_CONFIG /var/jenkins_config/casc.yaml 4 | COPY plugins.txt /usr/share/jenkins/ref/plugins.txt 5 | RUN jenkins-plugin-cli --plugin-file /usr/share/jenkins/ref/plugins.txt 6 | COPY casc.yaml /var/jenkins_config/casc.yaml 7 | 8 | -------------------------------------------------------------------------------- /006-NexusJenkinsVagrantCICD/plugins.txt: -------------------------------------------------------------------------------- 1 | credentials:1214.v1de940103927 2 | configuration-as-code:1559.v38a_b_2e3b_6b_b_7 3 | docker-workflow:528.v7c193a_0b_e67c 4 | job-dsl:1.81 5 | git:4.13.0 6 | github:1.36.0 7 | authorize-project:1.4.0 8 | matrix-auth:3.1.5 9 | job-restrictions:0.8 10 | view-job-filters:2.3 11 | nested-view:1.26 12 | # build-pipeline-plugin: The Jenkins project announced an unresolved security vulnerability affecting the current version of this plugin 13 | build-pipeline-plugin:1.5.7.1 14 | hashicorp-vault-plugin:359.v2da_3b_45f17d5 15 | pipeline-utility-steps:2.14.0 16 | pipeline-graph-view:143.v33ca_60725f13 17 | workflow-aggregator:590.v6a_d052e5a_a_b_5 18 | nexus-artifact-uploader:2.14 19 | -------------------------------------------------------------------------------- /006-NexusJenkinsVagrantCICD/src/main/java/HelloWorld.java: -------------------------------------------------------------------------------- 1 | import spark.servlet.SparkApplication; 2 | 3 | import static spark.Spark.get; 4 | 5 | public class HelloWorld implements SparkApplication { 6 | public static void main(String[] args) { 7 | new HelloWorld().init(); 8 | } 9 | 10 | @Override 11 | public void init() { 12 | get("/hello", (req, res) -> "Hello World"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /006-NexusJenkinsVagrantCICD/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | SparkFilter 8 | spark.servlet.SparkFilter 9 | 10 | applicationClass 11 | HelloWorld 12 | 13 | 14 | 15 | 16 | SparkFilter 17 | /* 18 | 19 | -------------------------------------------------------------------------------- /007-VaultFreeIPAVagrantIAM/.env: -------------------------------------------------------------------------------- 1 | HOSTNAME=ipa.devopsdaydayup.org 2 | DOMAIN=devopsdaydayup.org 3 | PASSWORD=admin123 4 | 5 | -------------------------------------------------------------------------------- /007-VaultFreeIPAVagrantIAM/.gitignore: -------------------------------------------------------------------------------- 1 | .secrets 2 | -------------------------------------------------------------------------------- /007-VaultFreeIPAVagrantIAM/vault-config.hcl: -------------------------------------------------------------------------------- 1 | storage "raft" { 2 | path = "/vault/data" 3 | node_id = "node1" 4 | } 5 | 6 | listener "tcp" { 7 | address = "0.0.0.0:8200" 8 | tls_disable = "true" 9 | #tls_cert_file = "/vault/vault.crt" 10 | #tls_key_file = "/vault/vault.key" 11 | #tls_client_ca_file = "/vault/vault.ca" 12 | } 13 | 14 | api_addr = "http://127.0.0.1:8200" 15 | cluster_addr = "https://127.0.0.1:8201" 16 | ui = true 17 | disable_mlock = true 18 | max_lease_ttl = "8784h" 19 | default_lease_ttl = "8784h" 20 | 21 | -------------------------------------------------------------------------------- /007-VaultFreeIPAVagrantIAM/vault.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM vault:1.12.1 2 | WORKDIR /vault/data 3 | COPY vault-config.hcl /vault/config/vault-config.hcl 4 | CMD vault server -config=/vault/config/vault-config.hcl 5 | -------------------------------------------------------------------------------- /008-AnsibleVagrantJenkinsDeployment/.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant* 2 | -------------------------------------------------------------------------------- /008-AnsibleVagrantJenkinsDeployment/hosts.ini: -------------------------------------------------------------------------------- 1 | jenkins_vm ansible_host=192.168.33.10 ansible_distribution="Ubuntu" ansible_connection=ssh ansible_user=admin 2 | -------------------------------------------------------------------------------- /008-AnsibleVagrantJenkinsDeployment/install-jenkins-role.yml: -------------------------------------------------------------------------------- 1 | # ansible-playbook install-jenkins.yml -i inventory.txt --ask-pass --ask-become-pass 2 | --- 3 | - hosts: jenkins_vm 4 | become: yes 5 | remote_user: admin 6 | become_user: root 7 | roles: 8 | - role: geerlingguy.jenkins 9 | -------------------------------------------------------------------------------- /008-AnsibleVagrantJenkinsDeployment/install-jenkins.yml: -------------------------------------------------------------------------------- 1 | # ansible-playbook install-jenkins.yml -i inventory.txt --ask-pass --ask-become-pass 2 | --- 3 | - hosts: jenkins_vm 4 | become: yes 5 | remote_user: admin 6 | become_user: root 7 | tasks: 8 | - name: Download Jenkins key 9 | get_url: 10 | url: https://pkg.jenkins.io/debian-stable/jenkins.io.key 11 | dest: /usr/share/keyrings/jenkins-keyring.asc 12 | - name: Add Apt source list 13 | lineinfile: 14 | path: /etc/apt/sources.list.d/jenkins.list 15 | line: "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/" 16 | create: yes 17 | - name: Run apt-get update 18 | apt: 19 | update_cache: yes 20 | - name: Install Java 21 | apt: 22 | name: openjdk-11-jre 23 | state: present 24 | - name: Install Jenkins 25 | apt: 26 | name: jenkins 27 | state: present 28 | -------------------------------------------------------------------------------- /008-AnsibleVagrantJenkinsDeployment/uninstall-jenkins.yml: -------------------------------------------------------------------------------- 1 | # ansible-playbook uninstall-jenkins.yml -i inventory.txt --ask-pass --ask-become-pass 2 | --- 3 | - hosts: jenkins_vm 4 | become: yes 5 | remote_user: admin 6 | become_user: root 7 | tasks: 8 | - name: Uninstall Jenkins 9 | apt: 10 | name: jenkins 11 | state: absent 12 | - name: Uninstall Java 13 | apt: 14 | name: openjdk-11-jre 15 | state: absent 16 | -------------------------------------------------------------------------------- /009-MinikubeHelmDeployment/images/github_page.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/009-MinikubeHelmDeployment/images/github_page.jpg -------------------------------------------------------------------------------- /010-MinikubeGrafanaPrometheusMultipassMonitoring/images/alert-rules-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/010-MinikubeGrafanaPrometheusMultipassMonitoring/images/alert-rules-1.png -------------------------------------------------------------------------------- /010-MinikubeGrafanaPrometheusMultipassMonitoring/images/chatgpg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/010-MinikubeGrafanaPrometheusMultipassMonitoring/images/chatgpg.png -------------------------------------------------------------------------------- /010-MinikubeGrafanaPrometheusMultipassMonitoring/images/grafana-query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/010-MinikubeGrafanaPrometheusMultipassMonitoring/images/grafana-query.png -------------------------------------------------------------------------------- /010-MinikubeGrafanaPrometheusMultipassMonitoring/images/prometheus-expression.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/010-MinikubeGrafanaPrometheusMultipassMonitoring/images/prometheus-expression.png -------------------------------------------------------------------------------- /010-MinikubeGrafanaPrometheusMultipassMonitoring/images/slack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/010-MinikubeGrafanaPrometheusMultipassMonitoring/images/slack.png -------------------------------------------------------------------------------- /010-MinikubeGrafanaPrometheusMultipassMonitoring/images/template-id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/010-MinikubeGrafanaPrometheusMultipassMonitoring/images/template-id.png -------------------------------------------------------------------------------- /010-MinikubeGrafanaPrometheusMultipassMonitoring/images/template-import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/010-MinikubeGrafanaPrometheusMultipassMonitoring/images/template-import.png -------------------------------------------------------------------------------- /010-MinikubeGrafanaPrometheusMultipassMonitoring/images/top-5-memory-intense-pod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/010-MinikubeGrafanaPrometheusMultipassMonitoring/images/top-5-memory-intense-pod.png -------------------------------------------------------------------------------- /010-MinikubeGrafanaPrometheusMultipassMonitoring/values.yaml: -------------------------------------------------------------------------------- 1 | grafana: 2 | enabled: true 3 | adminPassword: changeme 4 | -------------------------------------------------------------------------------- /011-KinDKubeconfigRBACConfiguration/readonly-manifest.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: readonly 6 | namespace: default 7 | --- 8 | apiVersion: v1 9 | kind: Secret 10 | metadata: 11 | name: readonly-token 12 | namespace: default 13 | annotations: 14 | kubernetes.io/service-account.name: readonly 15 | type: kubernetes.io/service-account-token 16 | 17 | --- 18 | apiVersion: rbac.authorization.k8s.io/v1 19 | kind: ClusterRole 20 | metadata: 21 | annotations: 22 | rbac.authorization.kubernetes.io/autoupdate: "true" 23 | labels: 24 | name: readonly-clusterrole 25 | namespace: default 26 | rules: 27 | - apiGroups: 28 | - "" 29 | resources: ["*"] 30 | verbs: 31 | - get 32 | - list 33 | - watch 34 | - apiGroups: 35 | - "" 36 | resources: 37 | - pods/exec 38 | - pods/portforward 39 | verbs: 40 | - create 41 | - apiGroups: 42 | - extensions 43 | resources: ["*"] 44 | verbs: 45 | - get 46 | - list 47 | - watch 48 | - apiGroups: 49 | - apps 50 | resources: ["*"] 51 | verbs: 52 | - get 53 | - list 54 | - watch 55 | --- 56 | apiVersion: rbac.authorization.k8s.io/v1 57 | kind: ClusterRoleBinding 58 | metadata: 59 | name: readonly-binding 60 | roleRef: 61 | apiGroup: rbac.authorization.k8s.io 62 | kind: ClusterRole 63 | name: readonly-clusterrole 64 | subjects: 65 | - kind: ServiceAccount 66 | name: readonly 67 | namespace: default 68 | -------------------------------------------------------------------------------- /012-CronjobVaultBackupHelmMinikube/.gitignore: -------------------------------------------------------------------------------- 1 | .vault.key 2 | -------------------------------------------------------------------------------- /012-CronjobVaultBackupHelmMinikube/helm-chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: vault-backup 3 | description: This Helm Chart is to backup vault data via both vault get api and consul snapshot 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.0.1 19 | 20 | 21 | # This is the version number of the application being deployed. This version number should be 22 | # incremented each time you make changes to the application. Versions are not expected to 23 | # follow Semantic Versioning. They should reflect the version the application is using. 24 | # It is recommended to use it with quotes. 25 | appVersion: "v0.1" 26 | 27 | -------------------------------------------------------------------------------- /012-CronjobVaultBackupHelmMinikube/images/minio-bucket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/012-CronjobVaultBackupHelmMinikube/images/minio-bucket.png -------------------------------------------------------------------------------- /012-CronjobVaultBackupHelmMinikube/images/minio-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/012-CronjobVaultBackupHelmMinikube/images/minio-console.png -------------------------------------------------------------------------------- /012-CronjobVaultBackupHelmMinikube/upload.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | # Check if the backup files exist or empty 4 | ls -trl /backup 5 | #CONSUL_BACKUP_FILE=/backup/$(ls /backup|grep consul) 6 | #if [ -f "$VAULT_BACKUP_FILE" ] && [ -f "$CONSUL_BACKUP_FILE" ] && [ ! -s "$VAULT_BACKUP_FILE" ] && [ ! -s "$CONSUL_BACKUP_FILE" ]; then echo "Files $VAULT_BACKUP_FILE and $CONSUL_BACKUP_FILE exist but have size 0" && exit 1; elif [ -f "$VAULT_BACKUP_FILE" ] && [ -f "$CONSUL_BACKUP_FILE" ]; then echo "Files $VAULT_BACKUP_FILE and $CONSUL_BACKUP_FILE exist and have size greater than 0"; else echo "One or both of the files $VAULT_BACKUP_FILE and $CONSUL_BACKUP_FILE do not exist" && exit 2; fi 7 | 8 | VAULT_BACKUP_FILE=/backup/$(ls /backup|grep vault) 9 | if [ -f "$VAULT_BACKUP_FILE" ] && [ -s "$VAULT_BACKUP_FILE" ] 10 | then 11 | echo "$VAULT_BACKUP_FILE exists! Backing up now..." 12 | else 13 | echo "Backup fails! Either the file doesn't exist or it is empty. Please check your script!" && exit 2 14 | fi 15 | 16 | # Copy backup files to minio object storage 17 | mc alias set local-minio http://$MINIO_ADDR:9000 $MINIO_USERNAME $MINIO_PASSWORD 18 | mc cp --recursive /backup/* local-minio/$BUCKET_NAME 19 | 20 | 21 | -------------------------------------------------------------------------------- /012-CronjobVaultBackupHelmMinikube/vault-backup-values.yaml: -------------------------------------------------------------------------------- 1 | # helm -n vault upgrade --install vault-backup helm-chart -f values.yaml 2 | cronjob: 3 | schedule: 0 2 * * 6 4 | imageUpload: minio/mc:RELEASE.2023-01-28T20-29-38Z 5 | imageVault: hashicorp/vault:1.9.2 6 | imageConsul: hashicorp/consul:1.12.0 7 | env: 8 | VAULT_ADDR: 'http://vault.vault-test:8200' 9 | VAULT_CACERT: '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt' 10 | #CONSUL_HTTP_ADDR: 'http://consul-server.vault-test:8500' 11 | #CONSUL_CACERT: '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt' 12 | VAULT_APPROLE_ROLE_ID: '' 13 | VAULT_APPROLE_SECRET_ID: '' 14 | MOUNT_POINT: 'kv-v2' 15 | SECRET_PATH: 'devops-secret' 16 | BUCKET_NAME: 'test' 17 | MINIO_USERNAME: 'rootuser' 18 | MINIO_PASSWORD: 'Test1234!' 19 | MINIO_ADDR: '.minio' 20 | 21 | -------------------------------------------------------------------------------- /012-CronjobVaultBackupHelmMinikube/vault-values.yaml: -------------------------------------------------------------------------------- 1 | 2 | injector: 3 | enabled: "-" 4 | replicas: 1 5 | image: 6 | repository: "hashicorp/vault-k8s" 7 | tag: "1.1.0" 8 | 9 | server: 10 | enabled: "-" 11 | image: 12 | repository: "hashicorp/vault" 13 | tag: "1.12.1" 14 | -------------------------------------------------------------------------------- /013-JavaMonitoryConfigmapMinikube/Dockerfile: -------------------------------------------------------------------------------- 1 | # First stage: complete build environment 2 | FROM maven:3.6.3-openjdk-17 AS builder 3 | # add pom.xml and source code 4 | ADD ./pom.xml pom.xml 5 | ADD ./src src/ 6 | # package jar 7 | RUN mvn clean package 8 | # Second stage: minimal runtime environment 9 | From maven:3.6.3-openjdk-17 10 | # copy jar from the first stage 11 | COPY --from=builder target/file-monitor-1.0.0.jar file-monitor-1.0.0.jar 12 | EXPOSE 8080 13 | ENTRYPOINT ["java", "-jar", "file-monitor-1.0.0.jar"] 14 | #CMD ["/config/game.properties", "3"] 15 | -------------------------------------------------------------------------------- /013-JavaMonitoryConfigmapMinikube/archive/configmap2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: test-demo 5 | data: 6 | test.txt: | 7 | enemy.types=aliens,monsters 8 | player.maximum-lives=5 9 | -------------------------------------------------------------------------------- /013-JavaMonitoryConfigmapMinikube/archive/file-monitor-1.0.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/013-JavaMonitoryConfigmapMinikube/archive/file-monitor-1.0.0.jar -------------------------------------------------------------------------------- /013-JavaMonitoryConfigmapMinikube/archive/pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: configmap-demo-pod 5 | spec: 6 | containers: 7 | - name: demo 8 | image: java-monitor-file:v1.0 9 | imagePullPolicy: Never 10 | env: 11 | # Define the environment variable 12 | - name: PLAYER_INITIAL_LIVES # Notice that the case is different here 13 | # from the key name in the ConfigMap. 14 | valueFrom: 15 | configMapKeyRef: 16 | name: game-demo # The ConfigMap this value comes from. 17 | key: player_initial_lives # The key to fetch. 18 | - name: UI_PROPERTIES_FILE_NAME 19 | valueFrom: 20 | configMapKeyRef: 21 | name: game-demo 22 | key: ui_properties_file_name 23 | volumeMounts: 24 | - name: config 25 | mountPath: "/config" 26 | readOnly: true 27 | volumes: 28 | # You set volumes at the Pod level, then mount them into containers inside that Pod 29 | - name: config 30 | configMap: 31 | # Provide the name of the ConfigMap you want to mount. 32 | name: game-demo 33 | # An array of keys from the ConfigMap to create as files 34 | items: 35 | - key: "game.properties" 36 | path: "game.properties" 37 | - key: "user-interface.properties" 38 | path: "user-interface.properties" 39 | -------------------------------------------------------------------------------- /013-JavaMonitoryConfigmapMinikube/archive/pod2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: configmap-demo-pod2 5 | spec: 6 | containers: 7 | - name: demo 8 | image: java-monitor-file:v1.1 9 | imagePullPolicy: Never 10 | volumeMounts: 11 | - name: config 12 | mountPath: "/tmp" 13 | readOnly: true 14 | volumes: 15 | # You set volumes at the Pod level, then mount them into containers inside that Pod 16 | - name: config 17 | configMap: 18 | # Provide the name of the ConfigMap you want to mount. 19 | name: test-demo 20 | -------------------------------------------------------------------------------- /013-JavaMonitoryConfigmapMinikube/archive/pod3.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: configmap-demo-pod-3 5 | spec: 6 | containers: 7 | - name: demo 8 | image: java-monitor-file:v1.3.0 9 | imagePullPolicy: Never 10 | env: 11 | # Define the environment variable 12 | - name: PLAYER_INITIAL_LIVES # Notice that the case is different here 13 | # from the key name in the ConfigMap. 14 | valueFrom: 15 | configMapKeyRef: 16 | name: game-demo # The ConfigMap this value comes from. 17 | key: player_initial_lives # The key to fetch. 18 | - name: UI_PROPERTIES_FILE_NAME 19 | valueFrom: 20 | configMapKeyRef: 21 | name: game-demo 22 | key: ui_properties_file_name 23 | volumeMounts: 24 | - name: config 25 | mountPath: "/config" 26 | readOnly: true 27 | volumes: 28 | # You set volumes at the Pod level, then mount them into containers inside that Pod 29 | - name: config 30 | configMap: 31 | # Provide the name of the ConfigMap you want to mount. 32 | name: game-demo 33 | # An array of keys from the ConfigMap to create as files 34 | items: 35 | - key: "game.properties" 36 | path: "game.properties" 37 | - key: "user-interface.properties" 38 | path: "user-interface.properties" 39 | -------------------------------------------------------------------------------- /013-JavaMonitoryConfigmapMinikube/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: game-demo 5 | data: 6 | game.properties: | 7 | enemy.types=aliens,monsters 8 | player.maximum-lives=5 9 | -------------------------------------------------------------------------------- /013-JavaMonitoryConfigmapMinikube/images/github-package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/013-JavaMonitoryConfigmapMinikube/images/github-package.png -------------------------------------------------------------------------------- /013-JavaMonitoryConfigmapMinikube/pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: configmap-demo-pod 5 | spec: 6 | containers: 7 | - name: demo 8 | image: java-monitor-file:v2.0 9 | imagePullPolicy: Never 10 | args: ["/config/game.properties", "3"] 11 | volumeMounts: 12 | - name: config 13 | mountPath: "/config" 14 | readOnly: false 15 | volumes: 16 | # You set volumes at the Pod level, then mount them into containers inside that Pod 17 | - name: config 18 | configMap: 19 | # Provide the name of the ConfigMap you want to mount. 20 | name: game-demo 21 | # An array of keys from the ConfigMap to create as files 22 | defaultMode: 0777 23 | items: 24 | - key: "game.properties" 25 | path: "game.properties" 26 | -------------------------------------------------------------------------------- /014-VaultInjectorMinikube/app-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app-deployment 5 | namespace: default 6 | labels: 7 | app: nginx 8 | spec: 9 | replicas: 3 10 | selector: 11 | matchLabels: 12 | app: nginx 13 | template: 14 | metadata: 15 | labels: 16 | app: nginx 17 | spec: 18 | serviceAccountName: app-sa 19 | containers: 20 | - name: nginx 21 | image: nginx:1.14.2 22 | ports: 23 | - containerPort: 80 24 | --- 25 | apiVersion: v1 26 | kind: ServiceAccount 27 | metadata: 28 | name: app-sa 29 | namespace: default -------------------------------------------------------------------------------- /014-VaultInjectorMinikube/patch-app-deployment.yaml: -------------------------------------------------------------------------------- 1 | spec: 2 | template: 3 | metadata: 4 | annotations: 5 | vault.hashicorp.com/agent-inject: 'true' 6 | vault.hashicorp.com/role: 'internal-app' 7 | vault.hashicorp.com/agent-inject-secret-database-config.txt: 'internal-app/data/database/config' 8 | vault.hashicorp.com/agent-inject-template-database-config.txt: | 9 | {{- with secret "internal-app/data/database/config" -}} 10 | {{ range $k, $v := .Data.data }} 11 | export {{ $k }}={{ $v }} 12 | {{ end }} 13 | {{- end }} -------------------------------------------------------------------------------- /014-VaultInjectorMinikube/values.yaml: -------------------------------------------------------------------------------- 1 | injector: 2 | replicas: 1 3 | image: 4 | repository: "hashicorp/vault-k8s" 5 | tag: "1.1.0" 6 | agentImage: 7 | repository: "hashicorp/vault" 8 | tag: "1.12.1" 9 | server: 10 | image: 11 | repository: "hashicorp/vault" 12 | tag: "1.13.1" 13 | ha: 14 | raft: 15 | config: | 16 | storage "raft" { 17 | path = "/vault/data" 18 | node_id = "node1" 19 | } 20 | 21 | listener "tcp" { 22 | address = "0.0.0.0:8200" 23 | tls_disable = "true" 24 | #tls_cert_file = "/vault/vault.crt" 25 | #tls_key_file = "/vault/vault.key" 26 | #tls_client_ca_file = "/vault/vault.ca" 27 | } 28 | 29 | api_addr = "http://0.0.0.0:8200" 30 | cluster_addr = "https://0.0.0.0:8201" 31 | ui = true 32 | disable_mlock = true 33 | max_lease_ttl = "8784h" 34 | default_lease_ttl = "8784h" 35 | 36 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChanceNPMProject/.funcignore: -------------------------------------------------------------------------------- 1 | *.js.map 2 | *.ts 3 | .git* 4 | .vscode 5 | local.settings.json 6 | test 7 | getting_started.md 8 | node_modules/@types/ 9 | node_modules/azure-functions-core-tools/ 10 | node_modules/typescript/ -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChanceNPMProject/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | csx 4 | .vs 5 | edge 6 | Publish 7 | 8 | *.user 9 | *.suo 10 | *.cscfg 11 | *.Cache 12 | project.lock.json 13 | 14 | /packages 15 | /TestResults 16 | 17 | /tools/NuGet.exe 18 | /App_Data 19 | /secrets 20 | /data 21 | .secrets 22 | appsettings.json 23 | local.settings.json 24 | 25 | node_modules 26 | dist 27 | 28 | # Local python packages 29 | .python_packages/ 30 | 31 | # Python Environments 32 | .env 33 | .venv 34 | env/ 35 | venv/ 36 | ENV/ 37 | env.bak/ 38 | venv.bak/ 39 | 40 | # Byte-compiled / optimized / DLL files 41 | __pycache__/ 42 | *.py[cod] 43 | *$py.class 44 | 45 | # Azurite artifacts 46 | __blobstorage__ 47 | __queuestorage__ 48 | __azurite_db*__.json -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChanceNPMProject/ChanceNodeHttpTrigger/function.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": [ 3 | { 4 | "authLevel": "function", 5 | "type": "httpTrigger", 6 | "direction": "in", 7 | "name": "req", 8 | "methods": [ 9 | "get", 10 | "post" 11 | ] 12 | }, 13 | { 14 | "type": "http", 15 | "direction": "out", 16 | "name": "res" 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChanceNPMProject/ChanceNodeHttpTrigger/index.js: -------------------------------------------------------------------------------- 1 | module.exports = async function (context, req) { 2 | context.log('JavaScript HTTP trigger function processed a request.'); 3 | 4 | const name = (req.query.name || (req.body && req.body.name)); 5 | const responseMessage = name 6 | ? "Hello, " + name + ". This HTTP triggered function executed successfully." 7 | : "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."; 8 | 9 | context.res = { 10 | // status: 200, /* Defaults to 200 */ 11 | body: responseMessage 12 | }; 13 | } -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChanceNPMProject/host.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "logging": { 4 | "applicationInsights": { 5 | "samplingSettings": { 6 | "isEnabled": true, 7 | "excludedTypes": "Request" 8 | } 9 | } 10 | }, 11 | "extensionBundle": { 12 | "id": "Microsoft.Azure.Functions.ExtensionBundle", 13 | "version": "[3.*, 4.0.0)" 14 | } 15 | } -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChanceNPMProject/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "start": "func start", 7 | "test": "echo \"No tests yet...\"" 8 | }, 9 | "dependencies": {}, 10 | "devDependencies": { 11 | "azure-functions-core-tools": "^4.x" 12 | } 13 | } -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChancePythonProject/.funcignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | .venv -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChancePythonProject/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | csx 4 | .vs 5 | edge 6 | Publish 7 | 8 | *.user 9 | *.suo 10 | *.cscfg 11 | *.Cache 12 | project.lock.json 13 | 14 | /packages 15 | /TestResults 16 | 17 | /tools/NuGet.exe 18 | /App_Data 19 | /secrets 20 | /data 21 | .secrets 22 | appsettings.json 23 | local.settings.json 24 | 25 | node_modules 26 | dist 27 | 28 | # Local python packages 29 | .python_packages/ 30 | 31 | # Python Environments 32 | .env 33 | .venv 34 | env/ 35 | venv/ 36 | ENV/ 37 | env.bak/ 38 | venv.bak/ 39 | 40 | # Byte-compiled / optimized / DLL files 41 | __pycache__/ 42 | *.py[cod] 43 | *$py.class 44 | 45 | # Azurite artifacts 46 | __blobstorage__ 47 | __queuestorage__ 48 | __azurite_db*__.json -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChancePythonProject/ChancePythonHttpTrigger/__init__.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | import azure.functions as func 4 | 5 | 6 | def main(req: func.HttpRequest) -> func.HttpResponse: 7 | logging.info('Python HTTP trigger function processed a request.') 8 | 9 | name = req.params.get('name') 10 | if not name: 11 | try: 12 | req_body = req.get_json() 13 | except ValueError: 14 | pass 15 | else: 16 | name = req_body.get('name') 17 | 18 | if name: 19 | return func.HttpResponse(f"Hello, {name}. This HTTP triggered function executed successfully.") 20 | else: 21 | return func.HttpResponse( 22 | "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.", 23 | status_code=200 24 | ) 25 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChancePythonProject/ChancePythonHttpTrigger/function.json: -------------------------------------------------------------------------------- 1 | { 2 | "scriptFile": "__init__.py", 3 | "bindings": [ 4 | { 5 | "authLevel": "function", 6 | "type": "httpTrigger", 7 | "direction": "in", 8 | "name": "req", 9 | "methods": [ 10 | "get", 11 | "post" 12 | ] 13 | }, 14 | { 15 | "type": "http", 16 | "direction": "out", 17 | "name": "$return" 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChancePythonProject/host.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "logging": { 4 | "applicationInsights": { 5 | "samplingSettings": { 6 | "isEnabled": true, 7 | "excludedTypes": "Request" 8 | } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChancePythonProject/requirements.txt: -------------------------------------------------------------------------------- 1 | # Do not include azure-functions-worker in this file 2 | # The Python Worker is managed by the Azure Functions platform 3 | # Manually managing azure-functions-worker may cause unexpected issues 4 | 5 | azure-functions -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChancePythonProject2/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | csx 4 | .vs 5 | edge 6 | Publish 7 | 8 | *.user 9 | *.suo 10 | *.cscfg 11 | *.Cache 12 | project.lock.json 13 | 14 | /packages 15 | /TestResults 16 | 17 | /tools/NuGet.exe 18 | /App_Data 19 | /secrets 20 | /data 21 | .secrets 22 | appsettings.json 23 | local.settings.json 24 | 25 | node_modules 26 | dist 27 | 28 | # Local python packages 29 | .python_packages/ 30 | 31 | # Python Environments 32 | .env 33 | .venv 34 | env/ 35 | venv/ 36 | ENV/ 37 | env.bak/ 38 | venv.bak/ 39 | 40 | # Byte-compiled / optimized / DLL files 41 | __pycache__/ 42 | *.py[cod] 43 | *$py.class 44 | 45 | # Azurite artifacts 46 | __blobstorage__ 47 | __queuestorage__ 48 | __azurite_db*__.json -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChancePythonProject2/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, render_template 2 | 3 | app = Flask(__name__) 4 | 5 | @app.route('/') 6 | def hello_world(): 7 | return "Hello, World!" 8 | 9 | if __name__ == '__main__': 10 | app.run(debug=True) -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChancePythonProject2/host.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "logging": { 4 | "applicationInsights": { 5 | "samplingSettings": { 6 | "isEnabled": true, 7 | "excludedTypes": "Request" 8 | } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChancePythonProject2/requirements.txt: -------------------------------------------------------------------------------- 1 | flask -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/app/ChancePythonProject2/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hello, World! 5 | 6 | 7 |

Hello, World!

8 | 9 | 10 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/archives/dev/datafactory.tf: -------------------------------------------------------------------------------- 1 | /** 2 | locals { 3 | datafacotry = { 4 | adf01 = { 5 | 6 | } 7 | } 8 | } 9 | **/ -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/archives/dev/function-apps.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | function-apps = { 3 | function_devops_01 = { 4 | app_service_plan_name = "devops-app-service-plan" 5 | app_service_plan_kind = "Linux" 6 | app_service_plan_reserved = "true" 7 | function_app_name = "devops-function-app-20230719" 8 | storage_account_access_key = "test" 9 | function_app_os_type = "linux" 10 | function_app_version = "~3" 11 | # TODO: Need to change it to dynamical value 12 | storage_account_name = "chance20230719001" 13 | sku = { 14 | app_service_plan_tier = "Dynamic" 15 | app_service_plan_size = "Y1" 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/archives/dev/main.auto.tfvars: -------------------------------------------------------------------------------- 1 | environment = "dev" 2 | rg_name = "devopsdaydayup2" 3 | location = "canadacentral" 4 | brand = "chance20230720" 5 | subscription_id = "c3e30486-02ef-4afb-9bc6-d4419197656e" 6 | tenant_id = "fc3bd05b-8c1f-41dd-9916-8b35dd923f7a" 7 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/archives/dev/main.tf: -------------------------------------------------------------------------------- 1 | module "main" { 2 | source = "../modules/dev" 3 | subscription_id = var.subscription_id 4 | tenant_id = var.tenant_id 5 | rg_name = var.rg_name 6 | location = var.location 7 | environment = var.environment 8 | brand = var.brand 9 | purpose = "devops" 10 | environment_instance = "01" 11 | storage-accounts = local.storage-accounts 12 | function-apps = local.function-apps 13 | } 14 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/archives/dev/naming_standards.tf: -------------------------------------------------------------------------------- 1 | ../naming_standards.tf -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/archives/dev/outputs.tf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/016-AzureFunctionTerraform/function-apps/archives/dev/outputs.tf -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/archives/dev/storage-account.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | storage-accounts = { 3 | storage1 = { 4 | purpose = "dev-use" 5 | environment_instance = "dev1" 6 | storage_instance = "1" 7 | storage_account_name = "chance20230719001" 8 | 9 | } 10 | storage2 = { 11 | purpose = "dev-use" 12 | environment_instance = "dev2" 13 | storage_instance = "2" 14 | storage_account_name = "chance20230719002" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/archives/dev/terraform.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.0.5" 3 | 4 | required_providers { 5 | azurerm = { 6 | source = "hashicorp/azurerm" 7 | version = "<=3.40.0" 8 | } 9 | } 10 | } 11 | 12 | provider "azurerm" { 13 | subscription_id = var.subscription_id 14 | tenant_id = var.tenant_id 15 | features {} 16 | } -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/archives/dev/variable.tf: -------------------------------------------------------------------------------- 1 | ../variables.tf -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/backend_modules/function-apps/function-apps.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_app_service_plan" "main" { 2 | name = var.app_service_plan_name 3 | location = var.location 4 | resource_group_name = var.rg_name 5 | kind = var.app_service_plan_kind 6 | reserved = var.app_service_plan_reserved 7 | 8 | sku { 9 | tier = var.app_service_plan_tier 10 | size = var.app_service_plan_size 11 | } 12 | } 13 | 14 | # resource "azurerm_function_app" "main" { 15 | # name = var.function_app_name 16 | # location = var.location 17 | # resource_group_name = var.rg_name 18 | # app_service_plan_id = azurerm_app_service_plan.main.id 19 | # storage_account_name = var.storage_account_name 20 | # storage_account_access_key = var.storage_account_access_key 21 | # os_type = var.function_app_os_type 22 | # version = var.function_app_version 23 | # } 24 | 25 | resource "azurerm_linux_function_app" "main" { 26 | name = var.function_app_name 27 | resource_group_name = var.rg_name 28 | location = var.location 29 | 30 | storage_account_name = var.storage_account_name 31 | storage_account_access_key = var.storage_account_access_key 32 | service_plan_id = azurerm_app_service_plan.main.id 33 | app_settings = { 34 | "FUNCTIONS_WORKER_RUNTIME" = "python" 35 | } 36 | 37 | site_config { 38 | # linux_fx_version = "Python|3.11" 39 | # ftps_state = "Disabled" 40 | } 41 | } -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/backend_modules/function-apps/variables.tf: -------------------------------------------------------------------------------- 1 | variable "app_service_plan_name" {} 2 | variable "environment" {} 3 | variable "location" {} 4 | variable "rg_name" {} 5 | variable "app_service_plan_kind" {} 6 | variable "app_service_plan_reserved" {} 7 | variable "app_service_plan_tier" {} 8 | variable "app_service_plan_size" {} 9 | variable "function_app_name" {} 10 | variable "storage_account_name" {} 11 | variable "storage_account_access_key" {} 12 | variable "function_app_os_type" {} 13 | variable "function_app_version" {} 14 | variable "app_service_plan_id" {} 15 | variable "linux_fx_versio" { 16 | default = "Python|3.11" 17 | } 18 | variable "ftps_state" { 19 | default = "Disabled" 20 | } -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/backend_modules/resource-group/resource-group.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_resource_group" "main" { 2 | name = var.rg_name 3 | location = var.location 4 | } -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/backend_modules/resource-group/variables.tf: -------------------------------------------------------------------------------- 1 | variable "rg_name" {} 2 | variable "location" {} 3 | 4 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/backend_modules/storage-account/locals.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | primary_name = format("%s", random_string.primary.result) 3 | replication = lower(var.environment) == "sandbox" ? "LRS" : contains(["dev", "qa", "nonprod"], lower(var.environment)) ? "GRS" : lower(var.environment) == "prod" && var.location == "canadacentral" ? "GZRS" : "RAGRS" 4 | default_tags = { 5 | environment = var.environment 6 | location = var.location 7 | resource_group = var.rg_name 8 | } 9 | tags = merge(local.default_tags, var.tags) 10 | } -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/backend_modules/storage-account/main.tf: -------------------------------------------------------------------------------- 1 | resource "random_string" "primary" { 2 | length = 3 3 | special = false 4 | upper = false 5 | } 6 | resource "azurerm_storage_account" "main" { 7 | name = var.name_override == null ? lower(format("%sst", replace(local.primary_name, "/[[:^alnum:]]/", ""))) : lower(replace(var.name_override, "/[[:^alnum:]]/", "")) 8 | resource_group_name = var.rg_name 9 | location = var.location 10 | account_tier = var.account_tier 11 | account_replication_type = var.replication_override == null ? local.replication : var.replication_override 12 | tags = local.tags 13 | } 14 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/backend_modules/storage-account/variables.tf: -------------------------------------------------------------------------------- 1 | variable "environment" {} 2 | variable "rg_name" {} 3 | variable "location" {} 4 | variable "account_tier" {} 5 | //variable "account_replication_type" {} 6 | variable "replication_override" {} 7 | variable "storage_account_name" {} 8 | variable "tags" {} 9 | variable "large_file_share_enabled" {} 10 | variable "name_override" { 11 | description = "Setting this will override the default naming convention but will still append 'st' to the end of the name" 12 | type = string 13 | default = null 14 | } -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/dev-working/datafactory.tf: -------------------------------------------------------------------------------- 1 | /** 2 | locals { 3 | datafacotry = { 4 | adf01 = { 5 | 6 | } 7 | } 8 | } 9 | **/ -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/dev-working/function-apps.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | function-apps = { 3 | function_devops_01 = { 4 | app_service_plan_name = "devops-app-service-plan" 5 | app_service_plan_kind = "Linux" 6 | app_service_plan_reserved = "true" 7 | function_app_name = "devops-function-app-20230719" 8 | storage_account_access_key = "RESVHtb6IIk9/5YmwF19k6ASNEiGwQpJeuDH/UmdjL2Z/ySlT+BYraBolW+p1Nh0rdyU/HV2e9qH+AStbMl5ag==" 9 | function_app_os_type = "linux" 10 | function_app_version = "~3" 11 | # TODO: Need to change it to dynamical value 12 | storage_account_name = "branddev01" 13 | sku = { 14 | app_service_plan_tier = "Dynamic" 15 | app_service_plan_size = "Y1" 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/dev-working/main.auto.tfvars: -------------------------------------------------------------------------------- 1 | environment = "dev" 2 | rg_name = "devopsdaydayup" 3 | location = "canadacentral" 4 | subscription_id = "c3e30486-02ef-4afb-9bc6-d4419197656e" 5 | tenant_id = "fc3bd05b-8c1f-41dd-9916-8b35dd923f7a" 6 | brand = "brand" 7 | purpose = "purpose" 8 | environment_instance = "01" -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/dev-working/main.tf: -------------------------------------------------------------------------------- 1 | module "main" { 2 | source = "../modules/dev" 3 | subscription_id = var.subscription_id 4 | tenant_id = var.tenant_id 5 | rg_name = var.rg_name 6 | location = var.location 7 | environment = var.environment 8 | brand = var.brand 9 | purpose = var.purpose 10 | environment_instance = var.environment_instance 11 | storage-accounts = local.storage-accounts 12 | function-apps = local.function-apps 13 | } 14 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/dev-working/naming_standards.tf: -------------------------------------------------------------------------------- 1 | ../naming_standards.tf -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/dev-working/outputs.tf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/016-AzureFunctionTerraform/function-apps/dev-working/outputs.tf -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/dev-working/storage_accounts.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | storage-accounts = { 3 | storage1 = { 4 | standard_storage_account_name = "chance20230719001" 5 | account_tier = "Standard" 6 | account_replication_type = "LRS" 7 | purpose = "devopschance" 8 | environment_instance = "dev01" 9 | storage_instance = "01" 10 | } 11 | storage2 = { 12 | standard_storage_account_name = "chance20230719002" 13 | account_tier = "Standard" 14 | account_replication_type = "LRS" 15 | purpose = "devopschance" 16 | environment_instance = "dev02" 17 | storage_instance = "02" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/dev-working/terraform.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.0.5" 3 | 4 | required_providers { 5 | azurerm = { 6 | source = "hashicorp/azurerm" 7 | version = "<=3.40.0" 8 | } 9 | } 10 | } 11 | 12 | provider "azurerm" { 13 | subscription_id = var.subscription_id 14 | tenant_id = var.tenant_id 15 | features {} 16 | } -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/dev-working/variable.tf: -------------------------------------------------------------------------------- 1 | ../variable.tf -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/modules/dev/datafactory.tf: -------------------------------------------------------------------------------- 1 | /** 2 | resource "azurerm_data_factory" "main" { 3 | name = "devopsdaydayup016" 4 | location = azurerm_resource_group.devopsdaydayup.location 5 | resource_group_name = azurerm_resource_group.devopsdaydayup.name 6 | identity { 7 | type = "SystemAssigned" 8 | } 9 | vsts_configuration { 10 | account_name = "" 11 | branch_name = "" 12 | project_name = "" 13 | repository_name = "" 14 | root_folder = "" 15 | tenant_id = "" 16 | } 17 | } 18 | **/ -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/modules/dev/function-apps.tf: -------------------------------------------------------------------------------- 1 | module "function-apps" { 2 | source = "../../backend_modules/function-apps" 3 | #version = "1.0.0" 4 | 5 | rg_name = var.rg_name 6 | location = var.location 7 | environment = var.environment 8 | 9 | for_each = var.function-apps 10 | 11 | function_app_name = lookup(each.value, "function_app_name", null) 12 | app_service_plan_name = lookup(each.value, "app_service_plan_name", null) 13 | app_service_plan_kind = lookup(each.value, "app_service_plan_kind", null) 14 | app_service_plan_reserved = lookup(each.value, "app_service_plan_reserved", null) 15 | app_service_plan_tier = lookup(each.value.sku, "app_service_plan_tier", null) 16 | app_service_plan_size = lookup(each.value.sku, "app_service_plan_size", null) 17 | app_service_plan_id = lookup(each.value, "azurerm_app_service_plan", null) 18 | storage_account_name = lookup(each.value, "storage_account_name", null) 19 | storage_account_access_key = lookup(each.value, "storage_account_access_key", null) 20 | function_app_os_type = lookup(each.value, "function_app_os_type", null) 21 | function_app_version = lookup(each.value, " function_app_version", null) 22 | 23 | depends_on = [module.storage-account] 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/modules/dev/naming_standards.tf: -------------------------------------------------------------------------------- 1 | ../../naming_standards.tf -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/modules/dev/rg.tf: -------------------------------------------------------------------------------- 1 | module "resource-group" { 2 | source = "../../backend_modules/resource-group" 3 | rg_name = var.rg_name 4 | location = var.location 5 | } -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/modules/dev/storage-account.tf: -------------------------------------------------------------------------------- 1 | module "storage-account" { 2 | source = "../../backend_modules/storage-account" 3 | #version = "1.0.0" 4 | 5 | rg_name = var.rg_name 6 | location = var.location 7 | environment = var.environment 8 | 9 | for_each = var.storage-accounts 10 | name_override = replace(local.standard_storage_account_name, "instance", each.value.storage_instance) 11 | storage_account_name = lookup(each.value, "storage_account_name", null) 12 | account_tier = lookup(each.value, "account_tier", "Standard") 13 | large_file_share_enabled = lookup(each.value, "large_file_share_enabled", false) 14 | replication_override = lookup(each.value, "replication_override", "LRS") 15 | tags = { 16 | purpose = each.value.purpose 17 | instance = each.value.environment_instance 18 | } 19 | depends_on = [module.resource-group] 20 | } 21 | 22 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/modules/dev/variable.tf: -------------------------------------------------------------------------------- 1 | ../../variable.tf -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/naming_standards.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | standard_storage_account_name = format("%s%sinstance", var.brand, var.environment) 3 | } 4 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/function-apps/variable.tf: -------------------------------------------------------------------------------- 1 | variable "environment" {} 2 | variable "brand" {} 3 | variable "rg_name" {} 4 | variable "location" {} 5 | variable "subscription_id" {} 6 | variable "tenant_id" {} 7 | variable "purpose" {} 8 | variable "environment_instance" {} 9 | 10 | variable "storage-accounts" { default = {} } 11 | variable "function-apps" { default = {} } 12 | -------------------------------------------------------------------------------- /016-AzureFunctionTerraform/variables.tf: -------------------------------------------------------------------------------- 1 | variable "environment" {} 2 | variable "rg_name" {} 3 | variable "location" {} 4 | variable "brand" {} 5 | variable "subscription_id" {} 6 | variable "tenant_id" {} 7 | 8 | variable "storage-accounts" { default = {} } 9 | variable "function-apps" { default = {} } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/images/azure-keyvault-secretexpirysolution.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/017-AzureLogicalAppTerraform/images/azure-keyvault-secretexpirysolution.jpg -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/backend_modules/app-service-plan/main.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_service_plan" "main" { 2 | name = var.app_service_plan_name 3 | resource_group_name = var.rg_name 4 | location = var.location 5 | os_type = var.os_type 6 | sku_name = var.sku_name 7 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/backend_modules/app-service-plan/outputs.tf: -------------------------------------------------------------------------------- 1 | 2 | output "service_plan_id" { 3 | value = azurerm_service_plan.main.id 4 | description = "The ID of the Service Plan" 5 | } 6 | 7 | output "service_plan_name" { 8 | value = azurerm_service_plan.main.name 9 | description = "The Serivce Plan name" 10 | } 11 | 12 | output "service_plan_kind" { 13 | value = azurerm_service_plan.main.kind 14 | description = "The Service Plan kind" 15 | } 16 | 17 | output "service_plan_reserved" { 18 | value = azurerm_service_plan.main.reserved 19 | description = "Whether this is a reserved Service Plan Type. true if os_type is Linux, otherwise false" 20 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/backend_modules/app-service-plan/variables.tf: -------------------------------------------------------------------------------- 1 | 2 | variable "app_service_plan_name" {} 3 | variable "rg_name" {} 4 | variable "location" {} 5 | variable "os_type" {} 6 | variable "sku_name" {} -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/backend_modules/logic-app-standard/app_service_plan.tf: -------------------------------------------------------------------------------- 1 | data "azurerm_service_plan" "existing" { 2 | count = try(length(var.app_service_plan.name) > 0, false) ? 1 : 0 3 | name = var.app_service_plan.name 4 | resource_group_name = var.resource_group_name 5 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/backend_modules/logic-app-standard/main.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_logic_app_standard" "main" { 2 | name = var.logicapp_name 3 | resource_group_name = var.resource_group_name 4 | location = var.location 5 | app_service_plan_id = var.app_service_plan.id 6 | storage_account_name = var.storage_account.name 7 | storage_account_access_key = var.storage_account.access_key 8 | app_settings = { 9 | "FUNCTIONS_WORKER_RUNTIME" = "node" 10 | "WEBSITE_NODE_DEFAULT_VERSION" = "~18" 11 | } 12 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/backend_modules/logic-app-standard/variables.tf: -------------------------------------------------------------------------------- 1 | variable "logicapp_name" {} 2 | variable "resource_group_name" {} 3 | variable "location" {} 4 | variable "app_service_plan" {} 5 | variable "storage_account" {} 6 | -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/backend_modules/resource-group/resource-group.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_resource_group" "main" { 2 | name = var.rg_name 3 | location = var.location 4 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/backend_modules/resource-group/variables.tf: -------------------------------------------------------------------------------- 1 | variable "rg_name" {} 2 | variable "location" {} 3 | 4 | -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/backend_modules/storage-account/locals.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | primary_name = format("%s", random_string.primary.result) 3 | replication = lower(var.environment) == "sandbox" ? "LRS" : contains(["dev", "qa", "nonprod"], lower(var.environment)) ? "GRS" : lower(var.environment) == "prod" && var.location == "canadacentral" ? "GZRS" : "RAGRS" 4 | default_tags = { 5 | environment = var.environment 6 | location = var.location 7 | resource_group = var.rg_name 8 | } 9 | tags = merge(local.default_tags, var.tags) 10 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/backend_modules/storage-account/main.tf: -------------------------------------------------------------------------------- 1 | resource "random_string" "primary" { 2 | length = 3 3 | special = false 4 | upper = false 5 | } 6 | resource "azurerm_storage_account" "main" { 7 | name = var.name_override == null ? lower(format("%sst", replace(local.primary_name, "/[[:^alnum:]]/", ""))) : lower(replace(var.name_override, "/[[:^alnum:]]/", "")) 8 | resource_group_name = var.rg_name 9 | location = var.location 10 | account_tier = var.account_tier 11 | account_replication_type = var.replication_override == null ? local.replication : var.replication_override 12 | tags = local.tags 13 | } 14 | -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/backend_modules/storage-account/outputs.tf: -------------------------------------------------------------------------------- 1 | output "stroage_account_name" { 2 | value = azurerm_storage_account.main.name 3 | description = "Name of storage account create" 4 | } 5 | 6 | output "storage_account_id" { 7 | value = azurerm_storage_account.main.id 8 | description = "ID of storage account create" 9 | } 10 | 11 | output "storage_account_primary_access_key" { 12 | value = azurerm_storage_account.main.primary_access_key 13 | description = "The primary accesss key for the storage account" 14 | sensitive = true 15 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/backend_modules/storage-account/variables.tf: -------------------------------------------------------------------------------- 1 | variable "environment" {} 2 | variable "rg_name" {} 3 | variable "location" {} 4 | variable "account_tier" {} 5 | //variable "account_replication_type" {} 6 | variable "replication_override" {} 7 | variable "storage_account_name" {} 8 | variable "tags" {} 9 | variable "large_file_share_enabled" {} 10 | variable "name_override" { 11 | description = "Setting this will override the default naming convention but will still append 'st' to the end of the name" 12 | type = string 13 | default = null 14 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/dev/app-service-plan.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | app-service-plan = { 3 | app_service_plan_01 = { 4 | rg_name = var.rg_name 5 | location = var.location 6 | app_service_plan_name = "devops-app-service-plan" 7 | os_type = "Windows" 8 | sku_name = "WS1" 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/dev/logic-app-standard.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | logic-apps = { 3 | function_devops_01 = { 4 | app_service_plan = { 5 | id = module.main.app_service_plan_id["app_service_plan_01"] 6 | } 7 | logicapp_name = "devops-function-app-20230719" 8 | storage_account = { 9 | name = module.main.strorage_account_name["storage1"] 10 | access_key = module.main.storage_account_access_key["storage1"] 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/dev/main.auto.tfvars: -------------------------------------------------------------------------------- 1 | environment = "dev" 2 | rg_name = "devopsdaydayup" 3 | location = "canadacentral" 4 | subscription_id = "c3e30486-02ef-4afb-9bc6-d4419197656e" 5 | tenant_id = "fc3bd05b-8c1f-41dd-9916-8b35dd923f7a" 6 | brand = "brand" 7 | purpose = "purpose" 8 | environment_instance = "01" -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/dev/main.tf: -------------------------------------------------------------------------------- 1 | module "main" { 2 | source = "../modules/dev" 3 | subscription_id = var.subscription_id 4 | tenant_id = var.tenant_id 5 | rg_name = var.rg_name 6 | location = var.location 7 | environment = var.environment 8 | brand = var.brand 9 | purpose = var.purpose 10 | environment_instance = var.environment_instance 11 | 12 | storage-accounts = local.storage-accounts 13 | app-service-plan = local.app-service-plan 14 | logic-apps = local.logic-apps 15 | 16 | } 17 | -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/dev/naming_standards.tf: -------------------------------------------------------------------------------- 1 | ../naming_standards.tf -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/dev/outputs.tf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/017-AzureLogicalAppTerraform/terraform/dev/outputs.tf -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/dev/storage_accounts.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | storage-accounts = { 3 | storage1 = { 4 | account_tier = "Standard" 5 | account_replication_type = "LRS" 6 | purpose = "devopschance" 7 | environment_instance = "dev01" 8 | storage_instance = "01" 9 | } 10 | storage2 = { 11 | account_tier = "Standard" 12 | account_replication_type = "LRS" 13 | purpose = "devopschance" 14 | environment_instance = "dev02" 15 | storage_instance = "02" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/dev/terraform.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.0.5" 3 | 4 | required_providers { 5 | azurerm = { 6 | source = "hashicorp/azurerm" 7 | version = "<=3.40.0" 8 | } 9 | } 10 | } 11 | 12 | provider "azurerm" { 13 | subscription_id = var.subscription_id 14 | tenant_id = var.tenant_id 15 | features {} 16 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/dev/variable.tf: -------------------------------------------------------------------------------- 1 | ../variable.tf -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/modules/dev/app-service-plan.tf: -------------------------------------------------------------------------------- 1 | module "app_service_plan" { 2 | source = "../../backend_modules/app-service-plan" 3 | 4 | for_each = var.app-service-plan 5 | app_service_plan_name = each.value.app_service_plan_name 6 | rg_name = each.value.rg_name 7 | location = each.value.location 8 | os_type = each.value.os_type 9 | sku_name = each.value.sku_name 10 | depends_on = [module.resource-group] 11 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/modules/dev/logic-app-standard.tf: -------------------------------------------------------------------------------- 1 | module "logic_app_standard" { 2 | source = "../../backend_modules/logic-app-standard" 3 | resource_group_name = var.rg_name 4 | location = var.location 5 | 6 | for_each = var.logic-apps 7 | logicapp_name = each.value.logicapp_name 8 | app_service_plan = each.value.app_service_plan 9 | storage_account = each.value.storage_account 10 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/modules/dev/naming_standards.tf: -------------------------------------------------------------------------------- 1 | ../../naming_standards.tf -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/modules/dev/output.tf: -------------------------------------------------------------------------------- 1 | // App Service Plan 2 | output "app_service_plan_name" { 3 | value = { for k, v in module.app_service_plan : k => v.service_plan_name } 4 | } 5 | 6 | 7 | output "app_service_plan_id" { 8 | value = { for k, v in module.app_service_plan : k => v.service_plan_id } 9 | } 10 | 11 | // Storage Account 12 | output "strorage_account_name" { 13 | value = { for k, v in module.storage-account : k => v.stroage_account_name } 14 | } 15 | 16 | output "storage_account_id" { 17 | value = { for k, v in module.storage-account : k => v.storage_account_id } 18 | } 19 | 20 | output "storage_account_access_key" { 21 | value = { for k, v in module.storage-account : k => v.storage_account_primary_access_key } 22 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/modules/dev/rg.tf: -------------------------------------------------------------------------------- 1 | module "resource-group" { 2 | source = "../../backend_modules/resource-group" 3 | rg_name = var.rg_name 4 | location = var.location 5 | } -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/modules/dev/storage-account.tf: -------------------------------------------------------------------------------- 1 | module "storage-account" { 2 | source = "../../backend_modules/storage-account" 3 | #version = "1.0.0" 4 | 5 | rg_name = var.rg_name 6 | location = var.location 7 | environment = var.environment 8 | 9 | for_each = var.storage-accounts 10 | name_override = replace(local.standard_storage_account_name, "instance", each.value.storage_instance) 11 | storage_account_name = lookup(each.value, "storage_account_name", null) 12 | account_tier = lookup(each.value, "account_tier", "Standard") 13 | large_file_share_enabled = lookup(each.value, "large_file_share_enabled", false) 14 | replication_override = lookup(each.value, "replication_override", "LRS") 15 | tags = { 16 | purpose = each.value.purpose 17 | instance = each.value.environment_instance 18 | } 19 | depends_on = [module.resource-group] 20 | } 21 | 22 | -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/modules/dev/variable.tf: -------------------------------------------------------------------------------- 1 | ../../variable.tf -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/naming_standards.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | standard_storage_account_name = format("%s%sinstance", var.brand, var.environment) 3 | } 4 | -------------------------------------------------------------------------------- /017-AzureLogicalAppTerraform/terraform/variable.tf: -------------------------------------------------------------------------------- 1 | variable "environment" {} 2 | variable "brand" {} 3 | variable "rg_name" {} 4 | variable "location" {} 5 | variable "subscription_id" {} 6 | variable "tenant_id" {} 7 | variable "purpose" {} 8 | variable "environment_instance" {} 9 | 10 | // Storage Account 11 | variable "storage-accounts" { default = {} } 12 | 13 | // App Service Plan 14 | variable "app-service-plan" { default = {} } 15 | // Logic App Standard 16 | variable "logic-apps" { default = {} } -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this application should be documented in this changelog file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) 6 | and the version format adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) 7 | 8 | 9 | ## [0.0.1] 2024-05-19 10 | 11 | ### Added 12 | 13 | - Requirement: Small startup company which only one development environment to star an application development 14 | - Initiate a CICD pipeline only including java compile, publish artifacts, download artifacts and deploy to an Azure Function app. -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline{ 2 | agent any 3 | 4 | tools { 5 | maven 'maven' 6 | jdk 'java' 7 | } 8 | 9 | stages{ 10 | stage('checkout'){ 11 | steps{ 12 | checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'github access', url: 'https://github.com/sreenivas449/java-hello-world-with-maven.git']]]) 13 | } 14 | } 15 | stage('build'){ 16 | steps{ 17 | bat 'mvn package' 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/archive/Dockerfile: -------------------------------------------------------------------------------- 1 | # Stage 1: Build 2 | FROM maven:3.8.1-openjdk-11 as build 3 | 4 | # Set the working directory in the image 5 | WORKDIR /app 6 | 7 | # Copy the pom.xml file 8 | COPY pom.xml . 9 | 10 | # Download all required dependencies into one layer 11 | RUN mvn dependency:go-offline -B 12 | 13 | # Copy your other files 14 | COPY src ./src 15 | 16 | # Build the project 17 | RUN mvn clean package -DskipTests 18 | 19 | # Stage 2: Application 20 | FROM openjdk:11-jre-slim 21 | 22 | # Set the working directory in the image 23 | WORKDIR /app 24 | 25 | # Copy the jar file from the build stage 26 | COPY --from=build /app/target/helloworld-1.0-SNAPSHOT.jar ./app.jar 27 | 28 | # Run the jar file 29 | ENTRYPOINT ["java","-jar","app.jar"] 30 | -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/archive/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.devopschance 6 | helloworld 7 | 1.0-SNAPSHOT 8 | 9 | 10 | 1.8 11 | 1.8 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | src/main/java/com/devopschance/helloworld 20 | 21 | 22 | maven-compiler-plugin 23 | 3.8.0 24 | 25 | 1.8 26 | 1.8 27 | 28 | 29 | 30 | maven-jar-plugin 31 | 3.1.0 32 | 33 | 34 | 35 | true 36 | lib/ 37 | com.devopschance.helloworld.HelloWorld 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/archive/src/main/java/com/devopschance/helloworld/HelloWorld.java: -------------------------------------------------------------------------------- 1 | package com.devopschance.helloworld; 2 | 3 | import java.time.LocalDateTime; 4 | import java.time.format.DateTimeFormatter; 5 | 6 | public class HelloWorld { 7 | 8 | public static void main(final String[] args) { 9 | final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("h:mm:ss a 'on' MMMM d, yyyy'.'"); 10 | final LocalDateTime now = LocalDateTime.now(); 11 | 12 | System.out.println("Hello, World! The current time is " + dtf.format(now)); 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/images/primeafces-in-out-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/018-AzureDevOpsJavaWebAppCICD/helloworld/images/primeafces-in-out-button.png -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/images/primeafces-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/018-AzureDevOpsJavaWebAppCICD/helloworld/images/primeafces-layout.png -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/images/primefaces-datatable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/018-AzureDevOpsJavaWebAppCICD/helloworld/images/primefaces-datatable.png -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/images/primefaces-todo-list-v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/018-AzureDevOpsJavaWebAppCICD/helloworld/images/primefaces-todo-list-v2.png -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/images/primefaces-todo-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/018-AzureDevOpsJavaWebAppCICD/helloworld/images/primefaces-todo-list.png -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/src/main/java/com/microsoft/azure/samples/dao/ItemManagement.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.azure.samples.dao; 2 | 3 | import com.microsoft.azure.samples.model.TodoItem; 4 | 5 | import java.util.List; 6 | 7 | public interface ItemManagement { 8 | 9 | public void addTodoItem(TodoItem item); 10 | 11 | public void updateTodoItem(List items); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/src/main/webapp/META-INF/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/src/main/webapp/WEB-INF/beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/src/main/webapp/WEB-INF/classes/logging.properties: -------------------------------------------------------------------------------- 1 | handlers = java.util.logging.ConsoleHandler 2 | .handlers = java.util.logging.ConsoleHandler 3 | 4 | java.util.logging.ConsoleHandler.level = ALL 5 | java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter 6 | 7 | com.microsoft.azure.samples.level = ALL 8 | -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/src/main/webapp/WEB-INF/faces-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ja_JP 6 | 7 | 8 | -------------------------------------------------------------------------------- /018-AzureDevOpsJavaWebAppCICD/helloworld/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Faces Servlet 8 | javax.faces.webapp.FacesServlet 9 | 1 10 | 11 | 12 | 13 | primefaces.THEME 14 | nova-light 15 | 16 | 17 | 18 | Faces Servlet 19 | *.xhtml 20 | 21 | 22 | 23 | index.xhtml 24 | 25 | 26 | 27 | javax.faces.PROJECT_STAGE 28 | Development 29 | 30 | -------------------------------------------------------------------------------- /019-TerraformAzureDevOpsWorkflow/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this application should be documented in this changelog file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) 6 | and the version format adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) 7 | 8 | 9 | ## [0.1.0] 2024-06-24 10 | ### Updated 11 | - Build Java code in Dockerfile 12 | - Pass over the image tag # from build job to deploy job 13 | - Complete the build/deploy process (Build: Checkout source code -> Maven/Ant/Gradle build -> PUblish Test Results -> Run Veracode Scan -> Docker Build -> Trivy Scan -> Publish Trivy Scan Result -> Docker push. Deploy: Update Image tag in Helm Value.yaml -> Donwload Secrets -> Replace tokens -> Deploy Helm Chart) 14 | - 15 | 16 | ## [0.0.1] 2024-05-19 17 | 18 | ### Added 19 | 20 | - Requirement: Small startup company which only one development environment to star an application development 21 | - Initiate a CICD pipeline only including java compile, publish artifacts, download artifacts and deploy to an Azure Function app. -------------------------------------------------------------------------------- /019-TerraformAzureDevOpsWorkflow/dev/dev01/ce/test.tf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/019-TerraformAzureDevOpsWorkflow/dev/dev01/ce/test.tf -------------------------------------------------------------------------------- /020-GithubActionJavaDockerfileCI/Dockerfile: -------------------------------------------------------------------------------- 1 | # Step 1: Use the latest Maven image with OpenJDK 2 | FROM maven:3.8-openjdk-17 AS build 3 | 4 | # Set the working directory 5 | WORKDIR /app 6 | 7 | # Copy the pom.xml file and download dependencies 8 | COPY pom.xml . 9 | RUN mvn dependency:go-offline -B 10 | 11 | # Copy the source code into the container 12 | COPY src ./src 13 | 14 | # Build the project 15 | RUN mvn clean install 16 | 17 | # Step 2: Use a lightweight OpenJDK image to run the application 18 | FROM openjdk:17-jdk-slim 19 | 20 | # Set the working directory 21 | WORKDIR /app 22 | 23 | # Copy the built JAR file from the build stage 24 | COPY --from=build /app/target/CurrentTimeProject-1.0-SNAPSHOT.jar app.jar 25 | 26 | # Expose the port 80 27 | EXPOSE 80 28 | 29 | # Run the application 30 | ENTRYPOINT ["java", "-jar", "app.jar"] 31 | -------------------------------------------------------------------------------- /020-GithubActionJavaDockerfileCI/docker-build-scan.yml: -------------------------------------------------------------------------------- 1 | name: Build, Scan, and Push Docker Image with Commit Hash 2 | 3 | on: 4 | push: 5 | paths: 6 | - '020-GithubActionJavaDockerfileCI/**' 7 | workflow_dispatch: 8 | 9 | jobs: 10 | build-and-scan: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | # Step 1: Check out the code 15 | - name: Checkout code 16 | uses: actions/checkout@v3 17 | 18 | # Step 2: Set up Docker 19 | - name: Set up Docker 20 | uses: docker/setup-buildx-action@v2 21 | 22 | # Step 3: Get Git commit hash 23 | - name: Get Git commit hash 24 | id: vars 25 | run: echo "GIT_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV 26 | 27 | # Step 4: Build Docker image with commit hash 28 | - name: Build Docker image 29 | run: | 30 | docker build -t ghcr.io/${{ github.repository_owner }}/current-time-app:${{ env.GIT_COMMIT }} ./020-GithubActionJavaDockerfileCI 31 | 32 | # Step 5: Log in to GitHub Container Registry 33 | - name: Log in to GitHub Container Registry 34 | uses: docker/login-action@v2 35 | with: 36 | registry: ghcr.io 37 | username: ${{ github.actor }} 38 | password: ${{ secrets.YOUR_GITHUB_TOKEN }} 39 | 40 | # Step 6: Push Docker image to GHCR 41 | - name: Push Docker image 42 | run: | 43 | docker push ghcr.io/${{ github.repository_owner }}/current-time-app:${{ env.GIT_COMMIT }} -------------------------------------------------------------------------------- /020-GithubActionJavaDockerfileCI/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.example 5 | CurrentTimeProject 6 | 1.0-SNAPSHOT 7 | 8 | 9 | 10 | org.apache.maven.plugins 11 | maven-compiler-plugin 12 | 3.8.1 13 | 14 | 17 15 | 17 16 | 17 | 18 | 19 | org.apache.maven.plugins 20 | maven-jar-plugin 21 | 3.3.0 22 | 23 | 24 | 25 | true 26 | lib/ 27 | com.example.CurrentTimeServer 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /020-GithubActionJavaDockerfileCI/src/main/java/com/example/CurrentTimeServer.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | import com.sun.net.httpserver.HttpServer; 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | import java.net.InetSocketAddress; 6 | import java.time.LocalTime; 7 | 8 | public class CurrentTimeServer { 9 | public static void main(String[] args) throws IOException { 10 | // Create an HTTP server listening on port 80 11 | HttpServer server = HttpServer.create(new InetSocketAddress(80), 0); 12 | 13 | // Define the handler for the root path 14 | server.createContext("/", exchange -> { 15 | String response = "Current Time: " + LocalTime.now(); 16 | exchange.sendResponseHeaders(200, response.getBytes().length); 17 | OutputStream os = exchange.getResponseBody(); 18 | os.write(response.getBytes()); 19 | os.close(); 20 | }); 21 | 22 | // Start the server 23 | System.out.println("Server is running..."); 24 | server.start(); 25 | } 26 | } -------------------------------------------------------------------------------- /021-GithubActionDockerImageFunctionCD/deploy-to-azure-function.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Docker Image to Azure Function 2 | 3 | on: 4 | push: 5 | paths: 6 | - '021-GithubActionDockerImageFunctionCD/**' 7 | workflow_dispatch: # Allows manual triggering of the workflow 8 | 9 | permissions: 10 | id-token: write 11 | contents: read 12 | 13 | jobs: 14 | deploy: 15 | name: Deploy to Azure Function 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | # Step 1: Log in to Azure 20 | - name: Log in to Azure 21 | uses: azure/login@v2 22 | with: 23 | client-id: ${{ secrets.AZURE_CLIENT_ID }} 24 | tenant-id: ${{ secrets.AZURE_TENANT_ID }} 25 | subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} 26 | auth-type: federated 27 | 28 | # Step 2: Deploy the Docker image to Azure Function 29 | - name: Deploy to Azure Function 30 | run: | 31 | az functionapp config container set \ 32 | --name ${{ vars.FUNCTION_APP_NAME }} \ 33 | --resource-group ${{ vars.RESOURCE_GROUP_NAME }} \ 34 | --docker-custom-image-name ${{ vars.IMAGE_NAME }}:${{ vars.IMAGE_TAG }} -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Core functionality - changes here should be rare! 2 | /src/app.py @chance2021 3 | /src/backend/database.py @chance2021 4 | /src/backend/routers/auth.py @chance2021 5 | 6 | # The frontend will need refactored soon to be more object oriented. 7 | /src/static/ @chance2021 8 | -------------------------------------------------------------------------------- /HelmOracleCloudK8s/README.md: -------------------------------------------------------------------------------- 1 | oci ce cluster create-kubeconfig --cluster-id $cluster_id --file $HOME/.kube/config --region ca-toronto-1 --token-version 2.0.0 --kube-endpoint PUBLIC_ENDPOINT 2 | 3 | alias k=kubectl 4 | 5 | 6 | helm repo add bitnami https://charts.bitnami.com/bitnami 7 | vi jenkins-values.yaml 8 | helm install jenkins bitnami/jenkins -f jenkins-values.yaml 9 | 10 | -------------------------------------------------------------------------------- /README.md.template: -------------------------------------------------------------------------------- 1 | # Project Name: 2 | 3 | ## Project Goal 4 | 5 | ## Table of Contents 6 | 1. [Prerequisites](#prerequisites) 7 | 2. [Project Steps](#project_steps) 8 | 3. [Post Project](#post_project) 9 | 4. [Troubleshooting](#troubleshooting) 10 | 5. [Reference](#reference) 11 | 12 | ## Prerequisites 13 | - Ubuntu 20.04 OS (Minimum 2 core CPU/8GB RAM/30GB Disk) 14 | - Docker(see installation guide [here](https://docs.docker.com/get-docker/)) 15 | - Docker Compose(see installation guide [here](https://docs.docker.com/compose/install/)) 16 | - Minikube (see installation guide [here](https://minikube.sigs.k8s.io/docs/start/)) 17 | - Helm (see installation guide [here](https://helm.sh/docs/intro/install/) 18 | 19 | 20 | ## Project Steps 21 | 22 | ### 1. Step 1 23 | 24 | ### 2. Step 2 25 | 26 | ## Post Project 27 | 28 | ## Troubleshooting 29 | 30 | ## Reference 31 | -------------------------------------------------------------------------------- /TerraformOracleCloudVM/tf-provider/README.md: -------------------------------------------------------------------------------- 1 | terraform apply -var-file=config/dev.tfvars 2 | 3 | export compartment_id="" 4 | export tenancy_id="" 5 | export availability_domain_name="" 6 | export shape_name="VM.Standard.E2.1.Micro" 7 | export instance_display_name="oci-created-vm-`date +%Y%m%d%H%M`" 8 | export image_id="ocid1.image.oc1.ca-toronto-1.aaaaaaaaf6jdknqhsavxre2dfdioc5qwudy2zhlhmpdyybi7pxcmgwtddqqa" 9 | export subnet_id="" 10 | export path_to_authorized_keys_file="/home//.ssh/id_rsa.pub" 11 | 12 | echo "compartment_id is $compartment_id" 13 | echo "tenancy_id is $tenancy_id" 14 | echo "availability_domain_name is $availability_domain_name" 15 | echo "shape_name is $shape_name" 16 | echo "instance_display_name is $instance_display_name" 17 | echo "image_id is $image_id" 18 | echo "subnet_id is $subnet_id" 19 | echo "path_to_authorized_keys_file is $path_to_authorized_keys_file" 20 | 21 | oci os ns get 22 | 23 | oci iam compartment list -c $tenancy_id 24 | 25 | oci compute image list -c $compartment_id 26 | 27 | oci compute instance launch --availability-domain $availability_domain_name -c $compartment_id --shape $shape_name --display-name $instance_display_name --image-id $image_id --ssh-authorized-keys-file $path_to_authorized_keys_file --subnet-id $subnet_id 28 | -------------------------------------------------------------------------------- /TerraformOracleCloudVM/tf-provider/availability-domains.tf: -------------------------------------------------------------------------------- 1 | 2 | data "oci_identity_availability_domains" "ads" { 3 | compartment_id = "ocid1.tenancy.oc1..aaaaaaaasueynrmsht7jdnxyd6n53sfz6ufpg2lj4dsmu6cwzapyxz6vrdia" 4 | } 5 | -------------------------------------------------------------------------------- /TerraformOracleCloudVM/tf-provider/compute.tf: -------------------------------------------------------------------------------- 1 | #resource "oci_core_instance" "bastion_instance" { 2 | # # Required 3 | # availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name 4 | # compartment_id = var.compartment_ocid 5 | # shape = var.instance_shape 6 | # source_details { 7 | # source_id = var.source_ocid 8 | # source_type = "image" 9 | # } 10 | # 11 | # # Optional 12 | # display_name = var.instance_name 13 | # create_vnic_details { 14 | # assign_public_ip = true 15 | # subnet_id = module.bastion-vcn.vcn_id 16 | # } 17 | # metadata = { 18 | # ssh_authorized_keys = file(var.ssh_public_key_path) 19 | # } 20 | # preserve_boot_volume = false 21 | #} 22 | -------------------------------------------------------------------------------- /TerraformOracleCloudVM/tf-provider/config/dev.tfvars: -------------------------------------------------------------------------------- 1 | instance_name="" 2 | ssh_public_key_path="" 3 | 4 | 5 | compartment_ocid="" 6 | region="ca-toronto-1" 7 | instance_shape="VM.Standard.E2.1.Micro" 8 | # Canonical-Ubuntu-22.04-2022.08.10-0 9 | # ocid1.image.oc1.ca-toronto-1.aaaaaaaaf6jdknqhsavxre2dfdioc5qwudy2zhlhmpdyybi7pxcmgwtddqqa 10 | source_ocid="ocid1.image.oc1.ca-toronto-1.aaaaaaaaf6jdknqhsavxre2dfdioc5qwudy2zhlhmpdyybi7pxcmgwtddqqa" 11 | -------------------------------------------------------------------------------- /TerraformOracleCloudVM/tf-provider/network.tf: -------------------------------------------------------------------------------- 1 | module "bastion-vcn"{ 2 | source = "oracle-terraform-modules/vcn/oci" 3 | version = "3.1.0" 4 | # insert the 5 required variables here 5 | 6 | # Required Inputs 7 | compartment_id = var.compartment_ocid 8 | region = var.region 9 | 10 | internet_gateway_route_rules = null 11 | local_peering_gateways = null 12 | nat_gateway_route_rules = null 13 | 14 | # Optional Inputs 15 | vcn_name = "vcn-module" 16 | vcn_dns_label = "vcnmodule" 17 | vcn_cidrs = ["10.0.0.0/16"] 18 | 19 | create_internet_gateway = true 20 | create_nat_gateway = true 21 | create_service_gateway = true 22 | } 23 | -------------------------------------------------------------------------------- /TerraformOracleCloudVM/tf-provider/output.tf: -------------------------------------------------------------------------------- 1 | output "name-of-first-availability-domain" { 2 | value = data.oci_identity_availability_domains.ads.availability_domains[0].name 3 | } 4 | -------------------------------------------------------------------------------- /TerraformOracleCloudVM/tf-provider/provider.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | oci = { 4 | source = "oracle/oci" 5 | version = "4.96.0" 6 | } 7 | } 8 | } 9 | provider "oci" { 10 | user_ocid = "" 11 | tenancy_ocid = "" 12 | #private_key_path = "" 13 | fingerprint = "" 14 | region = "ca-toronto-1" 15 | } 16 | -------------------------------------------------------------------------------- /TerraformOracleCloudVM/tf-provider/variables.tf: -------------------------------------------------------------------------------- 1 | variable "compartment_ocid" { 2 | type = string 3 | } 4 | 5 | variable "region" { 6 | type = string 7 | } 8 | 9 | variable "instance_shape" { 10 | type = string 11 | } 12 | 13 | variable "source_ocid" { 14 | type = string 15 | } 16 | 17 | variable "instance_name" { 18 | type = string 19 | } 20 | 21 | variable "ssh_public_key_path" { 22 | type = string 23 | } 24 | -------------------------------------------------------------------------------- /archive/018-AzureDevOpsFunctionRelease/20231005-Project-AzureKeyVaultSecretExpirySolution.md: -------------------------------------------------------------------------------- 1 | # Azure DevOps Function Release Workflow 2 | -------------------------------------------------------------------------------- /archive/018-AzureDevOpsFunctionRelease/README.md: -------------------------------------------------------------------------------- 1 | # Project Name: Azure DevOps Function Release Workflow 2 | 3 | ## Project Goal 4 | 5 | ## Table of Contents 6 | 7 | ## Prerequisites 8 | - An Azure subscription 9 | - Azure CLI 10 | - Terraform 11 | - Github Repository 12 | 13 | ## Project Steps 14 | 15 | ### 1. Login Azure 16 | 17 | ## Troubleshooting 18 | 19 | ## Reference -------------------------------------------------------------------------------- /cloud/azure/20230614-AzureLearningPlan.md: -------------------------------------------------------------------------------- 1 | # Azure学习规划 2 | 3 | 同学们好!首先感谢同学们昨晚参加我们的Git分享班会!也要感谢Zooey同学的百群联动和Yuyong同学的从中协调才能让这么多同学能聚在一起,共同学习。 4 | 5 | 昨天班会的最后我和大家说了我近期的一个想法,就是组织大家共同学习Azure。我的计划是分为三个阶段: 6 | - **第一阶段 - 介绍Azure常见服务** 7 | - **第二阶段 - 详细学习Azure DevOps** 8 | - **第三阶段 - 使用Terraform部署Azure常见服务** 9 | 10 | 第一阶段主要是带着大家把Azure上常见的服务都过一遍。这个顺序我打算按照从一个新手的角度,从登入[Azure Portal](https://portal.azure.com/)开始如何一步一步搭建自己想要的服务的这样一个顺序,把其中会涉及到服务都一一列出来,解释一遍,混个脸熟。这样无论你是公司工作需要使用Azure,还是自己个人做实验想要学习Azure,都能有一个比较好的抓手来进入这个庞杂的体系里。 11 | 12 | 目前我计划的学习内容顺序如下: 13 | - 1. **IAM** 14 | - 2. **Resource Management** 15 | - 3. **Location** 16 | - 4. **Resources** 17 | - 5. **ARM** 18 | - 6. **Cost Management** 19 | - 7. **Security** 20 | - 8. **DevOps** 21 | - 9. Hybris + Multi-Cloud 22 | - 10. Cloud Migration 23 | - 11. AI 24 | - 12. Machine Learning 25 | - 13. Cognitive Services 26 | - 14. Big Data 27 | - 15. Reporting 28 | - 16. Analytics 29 | - 17. IoT 30 | - 18. Maps Service 31 | 32 | 其中, 1 - 8节我们会花比较多的时间详细介绍,9 - 18节我们只是把涉及到的服务稍微解释一下就好。 33 | 34 | 我本身也只是刚刚开始接触Azure,很多知识点也不是很熟悉。写这些文章除了自己学习以外,其中一个重要的目的也是想能引起大家的讨论。所以大家如果有什么问题,或者你对某些服务很熟悉的话,也非常欢迎同学们在群里分享出来和大家一起讨论,这样才更能加强我们学习的效果。
35 | 36 | 好了,不多说了,我们下篇见! 37 | 38 | 39 | -------------------------------------------------------------------------------- /cloud/azure/20230706-IAM-ManagedIdentity.md: -------------------------------------------------------------------------------- 1 | # IAM - Managed Identity 2 | 在软件开发或者运维管理中, 有一个人人都头疼的问题:**密钥管理**。如何安全的使用密钥,从而让应用软件能正常访问对应服务,这是应用部署需要考虑的第一步。在Azure中就有这么一种特殊的**AAD**,它可以让用户在不知道具体密钥的情况下,就能访问对应服务。这个特殊的AAD就叫**Managed Identity**。在实际Azure的使用过程当中,应用需要链接其他服务之前,第一个需要访问的服务可能就是**Azure Key Vault**, 因为在**Azure Key Vault**里可以存储所有你需要的所有服务密钥信息。所以我们就可以通过**Managed Identity**来连接**Azure Key Vault**, 从而获取其他所有服务需要的密钥。这样的密钥管理就能简单很多。接下来我们来看看**Managed Identity**一些主要特性吧 3 | 4 | 1. 使用**Managed Identity**后,你就不需要管理任何密钥凭证(**Credential**)。甚至这些密钥凭证你压根就访问不了。 5 | 2. 只要对应资源**支持AAD授权登入**,你就能使用Managed Identity登入。 6 | 3. Managed Identity是Azure上的**免费**服务。 7 | 4. Managed Identity有两类,一类是**System-assigned**,还有一类是**User-assigned**。 8 | 5. Azure的一些资源(Resource)支持**System-assigned**,比如虚拟机(Virtual Machine)或App Service。它和对应资源是一对一的关系,生命周期一致(即资源删除后,对应Sysem-assigned managed identity也会被删除)。开启System-assigned managed identity之后,会有一个该资源名字一样的**Service Principal**生成,这个资源就能拿着这个**Service Principal**去访问那些已授权该**Service Principal**的服务。 9 | 6. 另一个类型**User-assigned**是一个**独立的Managed Identity**。这个Managed Identity独立于其他资源(Resource),并且可以被**多个**Resource使用。 10 | 7. 打个比方,我们的资源或应用相当于一辆汽车,对应要访问的资源相当于车库门,**System-assigned managed identity**相当于一个内置在我们汽车里的车库门钥匙,只要是这个汽车,就能开车库门,汽车销毁了,这个钥匙也作废了;而**User-assigned managed identity**相当于一个遥控钥匙,任何拥有这把钥匙的汽车,都能开启这个车库门。 11 | 12 | 13 | # Reference 14 | [Using Managed Identities](https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview) -------------------------------------------------------------------------------- /cloud/azure/20230712-IAM-PIM.md: -------------------------------------------------------------------------------- 1 | # PIM - Privileged Identity Management 2 | 在Azure AAD里有一个很有用的服务,叫做**Privileged Identity Management**. 这是个付费服务,并不是必须得,一些公司为**限制某些比较重要的资源的访问人数**,并且对该资源的操作做全面的监控,于是有了这样一个服务。 3 | 1. **PIM**使用范围有Azure AD, Azure, Microsoft 365, 以及 Azure平台上所有SaaS apps,例如AKS等 4 | 2. 通过**PIM**这个服务,管理员可以给某些用户限时权限(**just-in-time privileged access**)。也就是说,这个用户只有在某个指定的时间段内,才能对某些具体的资源,行使某些具体操作。而且该用户所做的所有行为都会记录在案。这就防止某些有权限的用户做了不恰当的操作。 5 | 3. **PIM**的权限的审批可以设置为**自动**和**手动**。首先你必须让你的管理员给你某个资源的某些特定PIM权限。当你拥有PIM权限后,你还不能马上对该资源进行相关访问或操作,你需要激活相关的**角色(Role)**。一般你进入对应需要申请PIM的资源,比如VM,然后再最左边的菜单栏里找到**Access control(IAM)** 这栏,点击进入,在**Check access**这个Tab下点击**View my access**。然后点击**Eligible assignments**,就能看到管理员允许你拥有的**角色(Role)**。选择你需要激活的角色(Role),点击**Activate role**,就能申请激活该角色(Role)了。如果是自动申请,你会在一两分钟内拥有该权限;如果是手动申请,你需要得到指定管理员的批准(Approve)才能拥有该角色。然后在一段时间后,你的角色(Role)就会被**撤销**。 6 | 4. AKS里使用PIM很好用,比如像QA或Staging,有时候开发人员需要登入去获取一些信息,就可以通过这样的方式控制访问。 -------------------------------------------------------------------------------- /cloud/azure/20230717-IAM-Intune.md: -------------------------------------------------------------------------------- 1 | # Intune 2 | 估计大部分的用户都没听说过**Microsoft Intune**这个产品。这很正常, 因为这是一款专门提供给**IT管理员**使用的管理软件。它针对的是如今越来越多公司开始给员工提供多种的工作形式的现状,比如公司会给你发笔记本或桌面电脑,或者公司允许你使用你自己的电脑,但是必须使用公司给你的Microsoft账户登入,甚至有一些公司允许员工自己使用自己的手机登入公司资源。那这就造成了有非常多种不同的设备需要IT部门来维护,维护的内容包括:**安全权限设置**,**访问权限设置**,**安全补丁更新**,等等。**Microsoft Intune**就针对这样一个痛点孕育而生了。 关于Intune,你只需要了解以下内容即可: 3 | 1. Microsoft Intune是一款基于**云端**的**终端设备管理解决方案**。 4 | 2. 它管理者**用户访问**,简化了应用在不同的设备上管理,其中包括手机,桌面电脑,虚拟机等等。 5 | 3. 它可以**保护**组织拥有的设备和用户个人设备上的访问和**数据**。 6 | 4. Intune具有**合规(compliance)**和**报告功能(reporting features)**,支持零信任安全模型。 7 | 8 | # Reference 9 | [What is intune](https://learn.microsoft.com/en-us/mem/intune/fundamentals/what-is-intune) -------------------------------------------------------------------------------- /cloud/azure/20230726-Compute-ACI.md: -------------------------------------------------------------------------------- 1 | # ACI (Azure Container Instance) 2 | 上一篇我们讲到了在Azure上部署微服务的利器:AKS。我们介绍了非常多在Azure上使用Kubernetes的好处,但是不管它好处再多,它依旧有一个致命的问题,就是,对于大部分非DevOps或刚刚入门DevOps的同学来说太不友好了,学习曲线相对其他技术都比较长。这就使得像CKA/CKAD这样的K8s考试一度含金量很高。但是对于很多只是想在云上使用到容器来运行他们自己的应用的同学来说,搭建一个AKS是一个很重且没有太多实际意义的事情。于是乎**Azure Container Instance**就这样在Azure家庭里孕育而生了。简单来说**ACI就是让用户可以在Azure云上以最快的速度部署简单应用容器的服务**。这里突出一下“**简单**”两个字,主要是想和复杂的AKS做一个区分。如果你的微服务应用架构非常复杂,那AKS可能更适合你。但是如果你就是一个很简单的应用服务,那就不用考虑AKS那么复杂的东西了,无脑选择ACI吧。人生很短,请放过自己 3 | 4 | 那我们来一起看看ACI有哪些值得注意的特点吧 5 | 1. **应用启动快**。和其他所有容器一样,与VM相比,ACI的启动速度快很多。我们在DevOps班会第一期讲Docker的时候反复说过一句话:**容器其实就是系统里的进程**。一个进程的启动当然比一个操作系统的启动快的多得多。 6 | 2. **网络访问方便**。相比于你在自己本地搭建的Docker容器,在云上用ACI创建容器一个最大的优势,就是能利用到Azure上的其他服务,尤其是网络服务,比如,你可以给你的容器申请**公网IP或域名**,这样其他互联网上的用户也能访问你部署在ACI容器里的应用了。你还可以使用Azure的**VPN gateway或ExpressRoute服务**,让你的应用容器更加安全的访问网络上的其他资源。 7 | 3. **更安全**。Azure比起一些自己搭建的容器,更能保证你的应用在容器里的隔离性。并且,ACI所部署的硬件环境也是更安全的(TEE: Trusted Execution Environment)。在TEE环境里,你传输的数据或者在内存里处理的数据都是加密的,非常安全。不过这是**可选项**,并且需要**额外付费**就是了。 8 | 4. **性能弹性**。你可以自由的调整你的ACI容器的**CPU核心数或则内存大小**,甚至你可以使用它们的**GPU资源**。这个不是你在本地可以轻易做到的事。 9 | 5. **存储**。你的ACI可以无缝的和Azure Storage 服务相连来存储你的应用数据。 10 | 6. **支持Linux和Windows容器**。Microsoft自家的产品,不支持Windows真有点说不过去... 11 | 7. ACI也支持像K8s里Pod的这样的服务,也就是**让多个容器共享一些资源**,包括网络,存储等。这比较适用于你要搜集你应用的日志或监控应用状态的情况。 12 | 8. **省钱**。如果你部署的应用没什么流量,不在乎偶尔的掉线,那么你可以选择使用它们的打折服务(Spot Container)。这个和VM里的概念一样,就是选择一些和他人共享的资源。这些资源在Azure资源充足的情况下都可以正常使用,但是一旦资源紧张,Azure可能就是暂时抽回这些资源,那么你的应用可能就得下线一段时间,直到资源再次充裕。虽然这会让你的服务可访问性受损,但是**高达70%**的折扣还是让广大勒紧裤腰带过日子的平民百姓们趋之若鹜! 13 | 14 | -------------------------------------------------------------------------------- /cloud/azure/20230728-Compute-AppService.md: -------------------------------------------------------------------------------- 1 | # Azure App Service 2 | 这两天我们介绍了Azure两个部署容器化应用很重要的服务:**AKS(Azure Kubernetes Service)**和**ACI(Azure Container Instance)**。如果你更近一步学习了这两个服务的使用之后,你会发现它们有一个共同的特征,就是它们都是用来**部署容器**的。上一篇我们讲到,**容器的本质就是进程,部署容器需要先构建容器镜像(Container Image)**。那么问题来了,作为一个开发人员,编写程序代码是我的天职,但是我要如何把做好的代码变成可以被部署的容器镜像呢?有经验的程序员就会说:“当然是创建Dockerfile,然后`docker build`一下就好啦"。但是你要知道,能说这句话的同学一定是已经对Docker容器比较熟悉的了。那不熟的同学是不是就无法部署ta的程序到Azure上了呢?当然不会啦,Azure还是很贴心的推出了另一个不需要构建容器就能部署你代码的服务:**Azure App Service**。值得注意的是,Azure App Serivce主要是针对**网站应用**场景,包括网站网页本身和一些Web APIs。
3 | 4 | 老样子,继续再熟悉一下Azure App Service有哪些特性吧 5 | 1. **支持许多编程语言**。Azure App Service支持现在市面上流行的大部分语言,比如ASP.NET, ASP.NET Core, Java, Ruby, Node.js, PHP或者Python。你也可以使用PowerShell或其他脚本作为后台服务。 6 | 2. 和我们之前说的Bastion VM一样,Azure App Serivce的底层操作系统完全由Azure托管,其中包括系统升级、维护、打补丁等,这些你都不用操心了,安心的写你的代码就好。 7 | 3. **支持容器**。如果你想的话,Azure App Service也是可以部署容器的。只是它除了容器,还是可以部署非容器的代码而已,选择更多。 8 | 4. 可以手动或自动**扩展性能**,保证你网站的高可用性。 9 | 5. 你可以和主流的SaaS平台(比如SAP/Salesforce)和本地数据相连。 10 | 6. **安全**,符合ISO, SOC, PCI等标准。 11 | 7. **认证方便**。你可以使用AAD, Google, Facebook, Twitter(X?)等你经常使用的认证平台来做你的应用认证。 12 | 8. **模版多**。你可以到Azure Marketplace里找到各种你可能会需要的模版,比如WordPress, Joomla, Drupal. 13 | 9. 最后值得一提的是在万能的**VSCode也有很好的插件支持** 14 | -------------------------------------------------------------------------------- /cloud/azure/20230729-Compute-AppServicePlan.md: -------------------------------------------------------------------------------- 1 | # App Service Plan 2 | 上一篇我们介绍了**Azure App Service**,我们知道程序员们除了使用AKS,ACI之外,还可以通过Azure App Service在不使用容器技术的前提下部署自己的网站到Azure上。今天我们会延续App Service的话题,来讲讲实现App Service需要涉及到的另一个重要概念,就是:**App Service Plan**。
3 | 简单来说,App Service Plan主要是定义了**一整套实现Azure App Service这个技术的计算资源**,比如说运行它的VM或Container。每次你创建一个App Service的时候,你都必须指定具体的App Service Plan来实施你的App Service部署。这个App Service Plan定义了以下一些资源: 4 | 1. 你所要使用的**操作系统**(Windows或Linux) 5 | 2. 资源所处的地区(**Region**)。这个对一些对数据归属地敏感的企业很重要。 6 | 3. 所需的**VM**(虚拟机)台数 7 | 4. VM(虚拟机)**大小**(Small, Medium, Large) 8 | 5. **价格等级** 9 | 10 | 关于价格等级(Pricing tier),我们可以来展开一下说说。Azure App Service Plan分为了以下这么些不同的等级: 11 | 1. **Shared Compute(共享计算资源)**:其中包括Free(免费)和Shared(共享)。这两个属于最基础的等级,它们会和其他不同用户部署的应用共同分享相同的Azure VM资源。 在这个等级里,Azure会给每一个应用程序分配CPU配额,大家一起共享资源。值得注意的是,这个等级的资源**无法扩展**。如果你的计算量太大,服务就容易挂了。所以这个等级只适合程序员自己开发和测试使用,千万不要用到生产环境了。 12 | 2. **Dedicated Compute(专用计算资源)**:这个等级有这么几类划分,分别是**Basic, Standard, Premium, PremiumV2和PremiumV3** 等级。这个等级里,你部署上去的应用会在你自己专门的Azure VMs里运行,不用和其他用户去争抢资源了,只有你自己部署的应用之间才共享资源。等级越高,背后拥有的VM数量越多,并且在你资源不足的时候可以扩展资源。 13 | 3. **Isolated(隔离计算资源)**:这是三个等级里最高等级,它除了和上一个等级一样让应用程序运行在自己专用的VM上,还拥有自己**专门的网络**,可以把你的计算资源进行隔离。并且性能的拓展也是最好了,属于钻石级别的会员待遇。这个等级还有一个独有的服务,叫做**App Service Environment**。具体不展开了,以后做实验的时候再说吧。 14 | 15 | 除了上面这些等级之间不同差异之外,每一个等级都提供一些不同服务,其中包裹**自定义域名,TLS/SSL证书,自动扩展性能,Deploymetn Slots, 容灾备份,Traffic Manager Intergration**等等。等级越高,能享有的服务越多。具体请参考微软官网文档吧。
16 | 17 | 最后提一下,一开始你不需要纠结选择购买哪个等级,因为你随时都可以切换不同的等级。所以最好的方法是,当你不太熟悉你的需求大小的时候,可以从Free开始,然后如果当前等级满足不了你,你再慢慢向上升级,直到找到符合你需求的等级就好啦。 18 | 19 | 20 | -------------------------------------------------------------------------------- /cloud/azure/20230731-Compute-AzureServiceFabric.md: -------------------------------------------------------------------------------- 1 | # Azure Service Fabric 2 | Google出品的Kubernetes已经在微服务领域家喻户晓,基本上可以说算的上是容器部署平台的事实标准。然而很多人却不太知道的是,微软其实也有它自己的微服务部署平台,这个平台支持着微软上许多明星产品,其中包括Azure SQL Database, Azure Costmos DB, Cortana, Microsoft Power BI, Microsoft Intune, Azure Event Hubs, Azure IoT Hub, Dynamics 365, Skype for Business等等,并且这个平台也在Azure上作为服务对外开放了,它就是**Azure Service Fabric**。
3 | 4 | **Azure Service Fabric**的知识体系和Kubernetes相似,非常庞杂,今天这篇文章主要是简单介绍一下这个服务,给同学们扩展一下知识边界,仅此而已。
5 | 6 | 那我们就来快速的的过一下**Azure Service Fabric**有哪些值得我们注意的特性吧。 7 | 1. Service Fabric是微软的**容器部署工具(container orchestrator)**,它主要是用来部署管理分布在集群服务器上的微服务。 8 | 2. Service Fabric最擅长管理的服务是**Stateful Microservices服务**。我们在第二期Kubernetes班会上知道,Kubernetes一开始最弱的项目就是对Stateful Microservices服务的部署和管理了,这一问题一直到Kuberenetes Statfulset的出现才有所好转。而**Service Fabric**恰恰相反,它的Stateful Microservices的管理是最优秀的,当然Stateless服务它也能管理,只是有点大材小用了。那为啥Service Fabric没有K8s有名呢?我也不知道,谁知道可以留言和大家分享。 9 | 3. Service Fabric提供一整套应用程序生命流程的服务,包括CI/CD, 部署,监控,维护,管理。Service Fabric和Azure Pipeline, Jenkins, Octopus Deploy都有非常好的集成。 10 | 4. Serivce Fabric集群可以部署在非常多不同的环境里,包括Azure云上或者你自己线下的数据中心,操作系统支持Windows和Linux。 -------------------------------------------------------------------------------- /cloud/azure/20230801-Compute-AzureStaticWebApp.md: -------------------------------------------------------------------------------- 1 | # Azure Static Web App 2 | 今天介绍另一个可以帮助你在Azure上部署网站的服务:**Azure Static Web App**。 这个服务是用来从代码仓库(Code Repository)里直接部署网站代码到Azure上用的。只要代码仓库里的数据一有变动,那么它就会借助CICD Pipeline(这里主要指的是GitHub或者Azure DevOps)自动部署到Azure上。每一次你Push或Pull Request到指定的Branch里,就会触发CICD构建并发布网站。它主要有这么些特性: 3 | 1. 可以部署像HTML,CSS, JavaScript和图片这样的静态资源 4 | 2. 可以集成Azure Function来提供后端API。 5 | 3. 主要是使用GitHub和Azure DevOps来做代码存储了和CICD构建发布 6 | 4. 借用了Azure的全球资源,可以让你的静态资源部署到离你的用户最近的位置 7 | 5. 免费SSL证书,并且自动更新 8 | 6. 提供自定义域名服务 9 | 7. 可以集成用户认证系统,包括Azure Active Directory, GitHub, Twitter(X) 10 | 8. 可以自定义Role definition和Role Assignments 11 | 9. 可以开启后端路由规则,全权控制访问路由 12 | 10. Azure CLI里也支持相关操作 -------------------------------------------------------------------------------- /cloud/azure/20230802-Compute-AzureSpringApps.md: -------------------------------------------------------------------------------- 1 | # Azure Spring Apps 2 | 上一篇介绍了一个特定场景的服务**Azure Static Web App**,这一篇我们来介绍一个特定编程语言的服务**Azure Sprint Apps**。看名字就知道,这个服务是专门针对Java应用的。如果你的应用是使用Spring Boot架构编写的,那么你不需要修改代码,就能直接使用这个服务把你的应用程序部署到Azure上去。在Azure上,它还提供全套应用生命周期管理服务,包括监控,排错,配置管理,服务发现,CICD集成,以及蓝绿部署等等。以下几个重要特征知道一下就好啦 3 | 4 | 1. 你可以非常高效的把你现有的Spring应用代码直接迁移到Azure上,并且在Azure上可以非常轻松的扩展并监控日常开销 5 | 6 | 2. 你可以结合Azure的监控服务,比如Azure Monitor, Azure Log Analytics来对你的应用进行监控和日志收集,也可以使用第三方服务,比如New Relic, Data Dog, ELK来监控和收集日志。 7 | 8 | 3. 它支持市面上大部分CICD相关构建部署服务,比如Azure DevOps, GitHub Action, Jenkins, Terraform, Gradle, Maven等等 9 | 10 | 4. 它有两种服务等级,一种是**Standard consumption**,还有一种是**Dedicated Plan**。前者是用多少花多少,后者是使用创建好的专门的计算资源来运行你的应用,就是前几篇我们说的App Service Plan。 11 | 12 | 5. 它还有企业级服务Enterprise plan。这个等级提供了VMWare Tanzu支持的服务,保证你的服务高可用。当然花销也不小。 -------------------------------------------------------------------------------- /cloud/azure/20230803-Compute-AzureFunctions.md: -------------------------------------------------------------------------------- 1 | # Azure Functions 2 | 今天来讲一个这几天我们小项目在做的实验项目:**Azure Functions**。Azure Functions可以算是我们这几天来讲到的Azure服务中虚拟化最多的服务了,前面几个虽然已经不太需要自己去配置VM了,但是还是需要提前布置好计算资源才能运行。而Azure Functions却是可以做到只要在你需要用到的时候才运行,用完就结束,直到你下次再使用的时候再被激活。它适合的应用场景包括:当有文件上传到Blob Storage的时候你需要运行程序,捕捉并且转化事件流,以及定时跑一些清理代码程序,等等。总的说,它就是一个靠**事件驱动(event-driven)的程序代码片段**,什么时候要用,什么时候才被激活。以下是你需要知道的它的一些特点: 3 | 1. 它是一整套**无服务解决方案(serverless solution)**,帮助你可以更专心在你的业务代码上,不用担心任何基础架构,更重要的是它用多少花多少的特性让你更加省钱。 4 | 2. 它支持基本上所有主流的语言,包括C#, Java, JavaScript, PowerSHell, Python,以及Rust和Go. 5 | 3. 它分为6个等级:Consumption plan, Premium plan, Dedicated plan, App Service Environment (ASE), Azure Container Apps和Kuberetes (Direct or Azure Arc) 6 | 4. **Consumption plan**: 这个等级就是前面提到的用多少花多少的等级。这个算是初级,省钱确实省,但是这两天弄实验的时候发现了很多局限,其中一个就是它的部署方式只支持Zip包发布,其他形式的发布都不支持。坑比较多,要小心。 7 | 5. **Premium plan**: 上面的Consumption plan还有一个很大的缺点,就是它冷启动慢,也就是你每次使用的时候需要等很长时间(5分钟左右)才能运行你的代码。Premium plan弥补了这个缺点,它帮你提前**预热**好了程序运行环境,不要等太久,就能得到反应。当然,代价就是贵一点。 8 | 6. **Dedicated plan**: 这个等级是让你的Function运行在**App Service Plan**的环境里。如果你已经有了App Service Plan,并且还有剩余的计算资源,建议选择这个等级。 9 | 7. **App Service Environment**: 这个就是高级版的App Service Plan,不仅享有独有的计算资源,还能拥有一个隔离的网络环境。如果你在乎安全,那就选这个吧。 10 | 8. **Azure Container Apps**:如果你已经创建了Azure Container Apps,那你还可以把你的Function部署到Azure Container App上运行。 11 | 9. **Kubernetes**: 如果你已经创建Kubernete,无论是Azure Kubernetes Service,还是你自己On-premise Kuberenetes,你都可以把你的Function部署到Kubernetes集群上。 -------------------------------------------------------------------------------- /cloud/azure/20230821-Compute-AzureLogicApp.md: -------------------------------------------------------------------------------- 1 | # Azure Logic App 2 | 上一篇我们介绍了需要写最少的代码就能发布程序的**Azure Function**,似乎这个虚拟化已经到了尽头。但是Azure还有一款产品,就算你不会也代码,也能创造一个程序,它就是**Azure Logic App**。
3 | 4 | 使用**Azure Logic App**的时候,你只需要通过Azure Portal的设计UI,以手动添加和拖拽的方式,就能够设计出一个属于你的程序或工作流。这有点像iPhone的Shortcut,你只要设置好触发事件以及之后的执行动作,就可以设计出一个自动化流程。比如以下场景: 5 | 1. 当一个文件上传的时候让Office 365给你发邮件通知。 6 | 2. 一旦密钥即将过期,可以自动创建一个Service Now Ticket让人来处理。 7 | 3. 重新路由并处理客户的订单从本地到云端的服务。 8 | 9 | 以下这些名词你需要了解一下: 10 | 1. **Workflow**: 这是一系列被定义的执行任务。一般**workflow**是由一个**Trigger**开始,之后执行各种定义好的**Action**. 11 | 2. **Trigger**: 这是**Workflow**的第一步,一般由某种事件触发,比如一个新的文件在Storage account里被创建出来。 12 | 3. **Action**: **Workflow**里的一系列被定义的任务,这些任务包括发送邮件,创建Service Now ticket,等等。 13 | 4. **Connector**: 一个**Connector**其实就代表着一个Operation,它可以是一个Trigger或一个Action,或者一个Trigger加Action的组合。Logica app的Connector有两种,**Build-in** connector 和 **Managed** connector。**Build-in** connector是直接在Azure Logic Apps里运行,效率比较高,但是种类不多;**Managed** connector是在Azure上部署和管理的,他主要是提供了一个代理或者API的Wrapper来帮助Azure Logic 和相关底层服务进行通讯。 14 | 5. **Integration Account**: 如果你使用了Azure B2B solutuion,你还可以创建一个Integration Account,它可以帮助你存储和管理B2B的artifacts。这个真没用过,所以也不是非常了解。 15 | 6. 对了, Logic app 还分成了两种模式,一种是Consumption还有一种是Standard。 它们的收费方式和使用方式也很不一样,感兴趣的同学可以到官网里看看。 16 | 17 | 最近我刚好接手一个Project是专门做利用Logic App来监测Azure Key Vault Secret Expiration的,有机会可以做成实验再和大家深入探讨一下。 -------------------------------------------------------------------------------- /cloud/azure/20230822-Compute-AzureBatch.md: -------------------------------------------------------------------------------- 1 | # Azure Batch 2 | **HPC**这个词不知道同学们有没有听说过。它的全称是**High-performance computing**(高性能计算),也叫做**Big Compute**。简单来说,它是由很多强算力的虚拟机组成的集群,这个算力包括CPU或者GPU,主要是给那些需要大量的算力运行的程序服务的。这些程序包括像是基因检测,石油勘探模拟,气候模型计算,图片处理,金融风险建模等等。这些程序动则就需要成百甚至上千上万的CPU/GUP来处理它们的计算量。很显然,我们前面提到的这些Azure服务都无法满足它。那今天我们介绍的**Azure Batch**,它就是Azure里的HPC服务。
3 | 4 | 传统的HPC集群的安装部署需要在本地数据库中心里圈出许多虚拟机,然后在这些虚拟机上安装一些HPC的代理服务,这样当客户递交计算申请的时候,HPC服务就能把这些计算任务分配给安装代理服务的虚拟机上,把计算量分担出去。这个项目在传统的IT里其实是需要巨大的计算机成本投入的。但是在云上,就能非常好的利用云的可伸缩性,用多少资源,付多少费用,可以很大程度上降低前期的固定成本投入,而且还能和Azure上的其他服务相互配合,比如Azure Storage Account, Azure Data Factory等,是一个很好的业务模型。
5 | 6 | 这里我们来介绍一个最简单的Azure Batch工作流程,方便你理解Azure Batch的工作方式。 7 | 1. 首先第一步,用户把需要处理的文件上传到Azure Storage Account里。这个文件可以是金融模型数据或者视频文件等等,也就是你要处理的信息。还可以包括一些你要处理数据的可执行脚本,比如说视频转译脚本文件。 8 | 2. 在你的Azure Batch账号里创建虚拟机集群以及选择虚拟机性能,比如需要多少台虚拟机,是Windows还是Linux得系统,还有哪些特殊的软件需要安装。然后创建一个使用这个软件执行数据的任务。 9 | 3. 接下来这些任务就会从第一步上传的Storage Account里下载数据文件到被分配的虚拟机上。 10 | 4. 然后这些数据就会在虚拟机上进行数据处理。在这个过程当中,虚拟机上的应用或服务会通过HTTPS向Azure Batch服务实时传递处理的进展状况。 11 | 5. 数据处理完成后,处理的结果就会被上传回Azure Storege。当然,如果你要是想的话,也可以直接到虚拟机上去下载结果。 12 | 6. 最后用户接到完成的通知后可以通过客户端应用或服务下载处理结果。 13 | 14 | 以上只是最简单的工作流程,还有一些功能其实Azure Batch也会提供的,比如在每个计算节点上进行多任务并行处理来缩短处理时间,或者你可以定义一些在任务开始之前或完成之后来执行的任务,可以为任务做准备,最后结束后清理数据现场。 -------------------------------------------------------------------------------- /cloud/azure/20230824-Compute-AzureVMwareSolution.md: -------------------------------------------------------------------------------- 1 | # AVS - Azure VMware Solution 2 | 对于很多政府部门或者国营企业,它们可能对安全有非常高的要求。这也导致公有云在这样的部门或企业里也很难被推广。关注安全的公司纷纷都转向了私有云的建设。然而构建自己的私有云成本相当的高,没有实力的公司压根要不起。并且维护私有云的成本也比公有云高的多的多。那有没有这么一个解决方案,既可以让企业享受类似公有云的便利,又能拥有私有云的安全呢?秉承着什么钱都必须争取赚的原则,Azure不出意外的也提供了这样一套解决方案,它就是:**Azure VMware Solution**.
3 | 4 | 看名字就知道,这是一个结合了VMware虚拟技术搭建的Azure服务。Azure VMware解决方案提供包含基于专用Bare Metal的物理服务器上的Azure基础架构构建的VMware vSphere集群的私有云。Azure VMware解决方案在Azure商业版和Azure政府版中都有提供。最小的初始部署是三个主机,但可以添加更多的主机,最多每个集群可添加16个主机。所有配置的私有云都配备有VMware vCenter Server、VMware vSAN、VMware vSphere和VMware NSX-T Data Center。因此,你可以将工作负载从本地环境迁移到这些私有云中,部署新的虚拟机(VM),并从你的私有云中使用Azure服务。
5 | 6 | 目前AVS(Azure VMware Solution)的机型有AV36, AV36P, AV52。 具体的性能参数可以参考官网。鉴于并非所有的人都有机会接触AVS服务(包括我自己),我就不过多介绍了(关键我也不懂啊)。看完这篇文章,知道有这么一个技术,就够了。 -------------------------------------------------------------------------------- /cloud/azure/20230830-Compute-AzureSpotVM.md: -------------------------------------------------------------------------------- 1 | # Azure Spot VM 2 | 云是个好东西,什么时候想用都可以用,不用自己买服务器。但是云的价格其实一点都不便宜,如果你实打实用三四年,那总的成本可能不亚于一次性买一台物理服务器的价格。那有没有什么办法能帮大家省点钱呢?有,但是你必须牺牲点东西,比如稳定性。如果你只是做个人实验用的,稳定性可能对于你来说并不是很大的问题,大不了重新再起一台新的服务器呗。又或者你只是想跑单次程序,比如Batch程序,那用完即焚是再正常不过了。如果你属于这类用户,Azure里有一款产品就非常适合你,它就是**Azure Spot VM**。
3 | 4 | **Azure Spot VM**的服务器和正常的服务本质没有什么区别,它其实是Azure想利用它的多余算力来再赚一点钱,反正闲着也是闲着嘛。只不过一旦Azure上的算力紧张,它就会立马收回这些算力,投入到那些正常付费的用户那里去。如果你不建议这样的不稳定性,你换来的是高达90%的折扣,也就是经常大街上听到的那句:“一折清仓大甩卖!”。
5 | 6 | 我们来通过以下这些点来了解一下**Azure Spot VM**有哪些特点吧 7 | 1. Azure Spot VM不提供SLA,因为它随时有可能把你的算力拿走,让你无法使用。 8 | 2. 一般会提前30秒通知你,给你做好退出服务器的准备。 9 | 3. 使用Azure Spot VM的时候你会被要求设置最大可以接受的价格,随着Azure资源的动态分配,你购买的Azure Spot VM的价格也会一直波动,一旦这个价格超过了你设置的最高价格限制,那你的服务就会被中断,直到你手动重启服务器才可以再次使用(如果启动后价格还是比你设置的最高价格高,就会报错)。 10 | 4. 如果你最高价格设置-1,你不会因为价格原因被强制退出。当然,这个价格再高也不可能超过当前市场正常机型的价格。 11 | 5. B系列和一些促销机型不支持Azure Spot VM。 -------------------------------------------------------------------------------- /cloud/azure/20230911-Network-TCP.md: -------------------------------------------------------------------------------- 1 | # TCP(Transmission Control Protocol) 2 | 前几篇,我们介绍了IP,知道了在网络中传输数据需要IP来定位接收方地址。但是在真实的网络中,我们传输一段数据并不是像寄信那样,把所有的信都塞进一个信封里,然后送到邮局去邮寄的,因为我们传输的内容可大可小,并且受限于底层物理介质设计,而且在网络里经常会出现丢包的事。于是网络的设计者就把要传送的数据切分成非常多的小数据包,然后再分别把这些数据包通过互联网传送给接收方,这些包可以是不同的”快递公司“传送,只要所有的包都成功运送,然后再通过特定的顺序还原,就能在接收方获得这封完整的"信件"了。要完成这套流程,我们就需要某些机制完成以下特定功能: 3 | - 确保接收方在线,要不然数据必将石沉大海 4 | - 发送之前把数据包按一定的序列拆分 5 | - 接受之后把数据包按一定的序列重组 6 | - 确保所有数据包没有丢失。如果有,识别出任何丢失的数据包,然后让发送方重发一遍,直到所有的包都收到为止。 7 | 8 | 很显然,以上这些功能我们的IP是无法做到的,于是另一种叫做TCP的协议机制就被设计出来,完成这些任务了。
9 | 10 | 在确认接收方在线的时候,TCP使用了很有名的三次握手方式(3-way handshake)。首先发送方向接收方发出一个请求,打了个招呼,问了一个你在微信上最讨厌别人问的问题:”你在吗?"。如果接收方在线,它就会回复说,“我在."。最后接收方就再发出一个确认说:"在就好,我准备发消息了哈"。这样三次交互之后,就建立了一个确定的通信渠道,这时候就可以把数据包按顺序拆分,然后通过网络里各种路径,发送给接收方。接收方收到数据包,确认没有包丢失后,再按照原先的序列重新把这些数据包组合起来,这就完成了一次数据传输了。
11 | 12 | 最后还要说一下,TCP还有一个类似功能的兄弟,UDP(User Datagram Protocol)。他俩最大的区别,就是UDP没有三次握手这样的确认机制,换句话说,使用UDP传输的数据没有安全保障,很有可能中途丢包。这个机制主要是针对那些注重实效但是不注重是否丢包的应用场景,比如游戏或者网络电话,丢个包少一针无所谓,但是延时太大就无法接受了。 13 | 14 | 其他所有Azure知识点,请查看:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/README.md -------------------------------------------------------------------------------- /cloud/azure/20230915-Network-NetworkSecurityGroup.md: -------------------------------------------------------------------------------- 1 | # NSG (Network Security Group) 2 | 讲了好几天网络基础知识,我们来再学习一些Azure里的网络服务吧。如果谈到Azure的网络安全,Network Security Group一定普通用户使用最频繁的一个。 -------------------------------------------------------------------------------- /docs/index.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | entries: 3 | test-service: 4 | - apiVersion: v2 5 | appVersion: 1.16.0 6 | created: "2022-12-10T19:25:21.067420246-05:00" 7 | description: A Helm chart for Kubernetes 8 | digest: 9fe1bd89c274fd1f8026477392bc888013c2a4d30a842523cb718dfadb3ded08 9 | name: test-service 10 | type: application 11 | urls: 12 | - https://chance2021.github.io/devopsdaydayup/test-service-0.1.0.tgz 13 | version: 0.1.0 14 | generated: "2022-12-10T19:25:21.066875514-05:00" 15 | -------------------------------------------------------------------------------- /docs/meeting_checkout.md: -------------------------------------------------------------------------------- 1 | > Note: Please refer [here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) for how to create a PR. 2 | # 2023.06.13 3 | [Google Meeting](https://meet.google.com/okb-spmd-rvn) 4 | -------------------------------------------------------------------------------- /docs/test-service-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/docs/test-service-0.1.0.tgz -------------------------------------------------------------------------------- /helm-charts/test-service/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm-charts/test-service/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: test-service 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.16.0" 25 | -------------------------------------------------------------------------------- /helm-charts/test-service/templates/hpa.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.autoscaling.enabled }} 2 | apiVersion: autoscaling/v2beta1 3 | kind: HorizontalPodAutoscaler 4 | metadata: 5 | name: {{ include "test-service.fullname" . }} 6 | labels: 7 | {{- include "test-service.labels" . | nindent 4 }} 8 | spec: 9 | scaleTargetRef: 10 | apiVersion: apps/v1 11 | kind: Deployment 12 | name: {{ include "test-service.fullname" . }} 13 | minReplicas: {{ .Values.autoscaling.minReplicas }} 14 | maxReplicas: {{ .Values.autoscaling.maxReplicas }} 15 | metrics: 16 | {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} 17 | - type: Resource 18 | resource: 19 | name: cpu 20 | targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} 21 | {{- end }} 22 | {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} 23 | - type: Resource 24 | resource: 25 | name: memory 26 | targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} 27 | {{- end }} 28 | {{- end }} 29 | -------------------------------------------------------------------------------- /helm-charts/test-service/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "test-service.fullname" . }} 5 | labels: 6 | {{- include "test-service.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: http 12 | protocol: TCP 13 | name: http 14 | selector: 15 | {{- include "test-service.selectorLabels" . | nindent 4 }} 16 | -------------------------------------------------------------------------------- /helm-charts/test-service/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "test-service.serviceAccountName" . }} 6 | labels: 7 | {{- include "test-service.labels" . | nindent 4 }} 8 | {{- with .Values.serviceAccount.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /helm-charts/test-service/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "test-service.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "test-service.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "test-service.fullname" . }}:{{ .Values.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /k8s-onbarding/images/k9s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/k8s-onbarding/images/k9s.png -------------------------------------------------------------------------------- /k8s-onbarding/images/vscode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/k8s-onbarding/images/vscode.png -------------------------------------------------------------------------------- /keycloak-integration/freeipa/.env: -------------------------------------------------------------------------------- 1 | HOSTNAME=ipa.test.org 2 | DOMAIN=test.org 3 | PASSWORD=admin123 4 | 5 | -------------------------------------------------------------------------------- /keycloak-integration/freeipa/images/group-mapper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/keycloak-integration/freeipa/images/group-mapper.png -------------------------------------------------------------------------------- /keycloak-integration/freeipa/images/ldap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/keycloak-integration/freeipa/images/ldap.png -------------------------------------------------------------------------------- /keycloak-integration/keycloak-upgrade/values-keycloak-16.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | tag: 16.1.0-debian-10-r0 3 | auth: 4 | adminUser: user 5 | adminPassword: "test1234!" 6 | service: 7 | type: ClusterIP 8 | extraEnvVars: 9 | - name: KEYCLOAK_LOGLEVEL 10 | value: DEBUG 11 | - name: WILDFLY_LOGLEVEL 12 | value: DEBUG 13 | - name: KEYCLOAK_PROXY_ADDRESS_FORWARDING 14 | value: "true" 15 | - name: KEYCLOAK_DATABASE_NAME 16 | value: "new_keycloak" 17 | -------------------------------------------------------------------------------- /keycloak-integration/keycloak-upgrade/values-keycloak-20.yaml: -------------------------------------------------------------------------------- 1 | # helm -n test-keycloak upgrade --install keycloak bitnami/keycloak --version 13.2.0 -f values-keycloak-20.yaml 2 | image: 3 | registry: docker.io 4 | repository: bitnami/keycloak 5 | tag: 20.0.5-debian-11-r4 6 | 7 | auth: 8 | adminUser: user 9 | adminPassword: "test1234!" 10 | service: 11 | type: ClusterIP 12 | extraEnvVars: 13 | - name: KEYCLOAK_LOGLEVEL 14 | value: DEBUG 15 | - name: WILDFLY_LOGLEVEL 16 | value: DEBUG 17 | - name: KEYCLOAK_PROXY_ADDRESS_FORWARDING 18 | value: "true" 19 | - name: KEYCLOAK_DATABASE_NAME 20 | value: "keycloak16" 21 | 22 | postgresql: 23 | enabled: false 24 | 25 | externalDatabase: 26 | host: "postgresql-for-keycloak20.test-keycloak" 27 | port: 5432 28 | user: bn_keycloak 29 | database: keycloak16 30 | password: "test1234!" 31 | -------------------------------------------------------------------------------- /keycloak-integration/keycloak-upgrade/values-postgres-15-for-keycloak-20.yaml: -------------------------------------------------------------------------------- 1 | # helm -n test-keycloak upgrade --install postgresql-for-keycloak20 bitnami/postgresql --version 12.2.2 -f values-postgres-12.yaml 2 | global: 3 | postgresql: 4 | auth: 5 | postgresPassword: "test1234!" 6 | username: "bn_keycloak" 7 | password: "test1234!" 8 | database: "keycloak20" 9 | image: 10 | registry: docker.io 11 | repository: bitnami/postgresql 12 | tag: 15.2.0-debian-11-r5 13 | 14 | -------------------------------------------------------------------------------- /linux/001-ls.md: -------------------------------------------------------------------------------- 1 | # ls - 列出目录 2 | 3 | 当你进入一个文件操作系统,你第一个想要做的事大概就是列出当前所在文件目录内容了。在Linux里,你可以使用`ls`这命令。`ls`可以记做是`list`的简写。它可以查看文件夹中所包含的文件及其详细信息(包括目录、文件夹、文件权限、文件所有者等)。以下是其常用命令 4 | ``` 5 | ls -a : 显示所有文件及目录,包括隐藏文件(. 开头的文件) 6 | ls -l : 列出除了文件名称外,亦将文件形态、权限、拥有者、文件大小等详细信息 7 | ls -1: 一次只列出一个文件,分行显示 8 | ls -r: 将文件以相反次序显示(英文字母次序) 9 | ls -t: 将文件依简历时间先后顺序列出 10 | ls -A: 同 -a, 但不列出 "." (目前目录)及“.." (父目录) 11 | ls -F: 在列出文件名称后加一符号;例如可执行挡则加 "*", 目录加“/" 12 | ls -R: 列出当前文件文件夹之下的所有文件 13 | ls -S: 将列出文件以文件大小排序,最越上面的文件大小越大 14 | ls -d: 只列出文件夹目录 15 | ls -B: 清除备份文件(以~结尾的文件) 16 | ls -h: human readable,看着舒服 17 | ``` 18 | 19 | ## 使用场景 20 | 1. 我自己经常用的就是`ls -trlh`这个命令,它除了查看详细信息,主要还是方便查看**最新变更过的文件** (`-t`代表按时间顺序排列;`-r`代表`reverse`按反方向排列; `-l`是`long`的简写; 表示列出详细文件信息,包括大小,时间,权限等等; `-h`代表用`human`人类可读的方式显示结果,比如会帮你换算文件大小,变成GB或MB或KB这样好读的单位,而不是全部都是KB)。 21 | 2. 一般还会用`ll` 快捷键(有些版本Linux不是默认选项,可以设置一下`alias ll='ls -alF'` ),相当于使用`ls -l`的效果,查看具体文件信息。 22 | 3. 还有一个比较有用的命令是`ls -lS`。 `-S`表示按照文件大小以此排序。 23 | 4. 对了,默认情况下`ls`是不显示隐藏文件的。所谓的隐藏文件就是以`.`开头的文件,比如`.filename1`。如果你想要显示,可以使用`-a`是个选项,比如`ls -lSa`,这样就可以把包括隐藏文件在内的所有文件按照大小排列出来了。 24 | 25 | > 注意: 26 | > - 1. 在脚本中,尽量写出完整的ls命令和参数。为了避免系统之间的alias不同引起脚本不工作。 27 | > - 2. 可以使用find命令代替查找文件。尤其在脚本中, `find . -type f`,这个可以列出当前文件夹下所有文件,包括子文件夹里的文件。 28 | -------------------------------------------------------------------------------- /linux/002-cd.md: -------------------------------------------------------------------------------- 1 | # cd - 更换目录 2 | 上一篇我们学习了如何查看当前目录内容,那下一步我们经常想做的就是进入其他目录里看看,直到找到想要的目录。这个时候我们就需要使用`cd`这个命令了。`cd`是`change directory`的简写,表示切换目录,这个操作就像你在Winodws电脑里双击某个文件夹进入这个目录的效果一样。当然,如果你知道你想去的目录的绝对路径,你也可以直接去,这个后续我们在讲Linux目录结构的时候会重点介绍一下相对路径和绝对路径的概念。下面是`cd`的一些常见使用命令: 3 | ``` 4 | cd [-L|[-P [-e]] [-@]] [dir] 5 | Options: 6 | -L 强制跟随符号链接: 在处理 ".." 实例之后解析 DIR 中的符号链接。 7 | -P 使用物理目录结构而不是跟随符号链接: 在处理 ".." 实例之前解析 DIR 中的符号链接。 8 | -e 如果提供了 -P 选项并且无法成功确定当前工作目录,则以非零状态退出。 9 | -@ 对于支持此功能的系统,在一个包含文件属性的目录中呈现一个具有扩展属性的文件。 10 | ``` 11 | 12 | ## 使用场景 13 | 1. 只要在`cd`后面加上一个绝对路径,就能去到操作系统中你想要去的地方(前提当然是这个文件夹存在了)。比如: `cd /tmp` 14 | 2. 如果你想返回上层目录,你可以用这个命令:`cd ..`。 `..`表示上层目录,`.`表示当前目录。 15 | 3. 如果你想去你的Home目录,你可以直接输入 `cd ~`。 16 | 4. 如果你是从其他地方跳到这个目录,你想跳回到原来的目录,你可以输入 `cd -`。这就像是电视遥控器的返回上一个节目的按钮(不知道有多少人还记的这个功能了)。 17 | 5. 最后一个小技巧可以使用在脚本里,就是把上一条指令的目录地址作为跳转目录,你可以这样操作 `cd $_`。举个例子: 18 | ``` 19 | mkdir /tmp/new_folder 20 | cd $_ 21 | ``` 22 | 上面的`$_`就代表了`/tmp/new_folder`。很省事吧。 23 | 24 | -------------------------------------------------------------------------------- /linux/003-pwd.md: -------------------------------------------------------------------------------- 1 | # pwd - 显示目前所在目录路径 2 | 前两篇我们了解了在Linux操作系统里如何显示目录内容以及如何去到你想要去的目录。那这篇我们就来看看如果查看当前所在目录路径。和图形桌面操作系统不同,使用命令行显示的操作系统并不能那么直观的了解你所在的当前位置(当然也有方法,就是修改你的命令符提示,一会儿会说说)。第一次使用命令窗口的同学一定会有好像被突然抛入沙漠的那种无所适从感,当下你最想知道的一定是:我这是在哪里?!Linux系统里的`pwd`就是告诉你身处何方的“卫星定位仪"。`pwd`是`Print Working Directory`的简写,表示让系统打印出你当前工作所在目录路径。常见参数有: 3 | ``` 4 | -P: 显示正确的目录名称,而不是以链接文件的路径来显示 5 | ``` 6 | 7 | ## 使用场景 8 | 1. 一般正常使用的话直接输入`pwd`就好了。 9 | 2. 上面这个参数`-P`主要是用来显示链接文件(快捷方式文件)的真实目录路径,比如: 10 | ``` 11 | ln -s test-folder test-folder-link 12 | $ ls -trl 13 | total 0 14 | drwxr-xr-x 2 chance staff 64 May 14 09:19 test-folder 15 | lrwxr-xr-x 1 chance staff 11 May 14 09:19 test-folder-link -> test-folder 16 | 17 | $ cd test-folder-link 18 | $ pwd 19 | /Users/chance/github/test-folder-link 20 | 21 | chance@devops test-folder-link % pwd -P 22 | /Users/chance/github/test-folder 23 | ``` 24 | 3. 大多数shell都有环境变量`PWD`,里面也会包含当前目录路径,这个可以在脚本中使用: 25 | ``` 26 | echo $PWD 27 | /Users/chance/github/test-folder-link 28 | ``` 29 | 4. 如果你想更直观的知道自己的位置,你可以配置`PS1`这个环境变量,它能改变你命令行的提示符哦 30 | ``` 31 | export PS1='$(whoami)@$(hostname):$(pwd)' 32 | chance@devops.local:/tmp/git-lab 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /linux/004-mkdir.md: -------------------------------------------------------------------------------- 1 | # mkdir (make directory): 创建一个新的目录 2 | 前几篇我们学习了如何在Linux里“逛街”,浏览文件系统里的文件。这一篇我们来看看如何在Linux里创建一个文件夹。
3 | 4 | ## 使用方法 5 | `mkdir ` 6 | 7 | 在Linux创建文件夹只需要输入`mkdir`然后跟上文件夹名称就好。如果没有带上文件完整路径,那就会在当前文件夹下创建一个新的文件夹。 8 | 9 | ## 常见参数 10 | `-p`: 自动帮你建立多层目录
11 | `-m`: 强制设定文件夹属性
12 | `-v`: 打印文件名
13 | 14 | ## 使用场景 15 | 1. 如果你想建立多层文件夹,且其中有些**文件夹并不存在**,那么必须使用`-p`参数,比如 16 | ``` 17 | mkdir devops/lesson1/lab1/img 18 | mkdir: cannot create directory ‘devops/lesson1/lab1/img’: No such file or directory 19 | 20 | # 这时候你就需要加上-p 来帮你自动建立多层目录... 21 | /tmp$ mkdir -p devops/lesson1/lab1/img;cd $_ 22 | osboxes@osboxes:/tmp/devops/lesson1/lab1/img$ 23 | ``` 24 | 复习一下, `cd $_` 意思是把前一个命令里的路径(mkdir 后的 路径)作为下一个命令(cd)的输入。
25 | 26 | 2. 如果你想要让新建的文件**强制设定属性**,你可以使用`-m`参数,比如 27 | ``` 28 | $ mkdir -m777 newfolder 29 | bash-3.2$ ls -trl 30 | drwxrwxrwx 2 chance wheel 64 31 May 08:44 newfolder 31 | ``` 32 | 3. 默认情况下如果文件夹创建成功系统是不会有任何反馈的(毕竟**在Unix系统里,没有消息就是最好的消息**)。但是如果你想让系统返回一些啥,你可以带上`-v`这个参数,**系统就会返回文件夹的名字**了。 33 | ``` 34 | bash-3.2$ mkdir newfolder01 35 | bash-3.2$ mkdir -v newfolder02 36 | newfolder02 37 | ``` 38 | -------------------------------------------------------------------------------- /linux/005-rmdir.md: -------------------------------------------------------------------------------- 1 | # rm or rmdir (remove directory) 删除一个文件或目录 2 | 昨天我们学习了如何在Linux创建一个目录,那今天我们来看看如何删除一个目录。我们可以使用`rm ` 来删除一个目录。注意了,如果不带参数的话只能删除一个空的目录,否则会报错。这是两个危险的命令,网上看到那种删库跑路的文章中经常提到的命令。记得永远不要在这命令之后加上 /, 因为在Linux系统中,/ 代表根目录,也就是这个系统里所有的目录都在这个目录之下创建的。打一个不严谨的比喻,相当于你的系统只有一个C:盘,删了这个C:,你所有的文件都会被删除。使用的时候要小心,否则很容易受到法律的制裁。。 3 | 4 | ## 常见参数 5 | ``` 6 | -r: 如果要删除的目录里面还有其他文件或文件夹,需要带上这个参数 7 | -f: 强制删除 8 | -p: 删除多层目录 9 | ``` 10 | 11 | ## 使用场景 12 | 1. 删除一个非空目录,需要使用`-r`参数,例如: `rmdir -r ` 13 | 2. 删除一个非空目录的时候系统会提示,问你是否删除,如果你不想要提示,想要强制删除,你可以使用`-f`参数,例如:`rmdir -f ` 14 | 3. 写Script的时候非常忌讳以下写法: 15 | ``` 16 | APP_PATH=xxxxxx 17 | FILE=xxxxxx 18 | rm -r ${APP_PATH}/${FILE} 19 | ``` 20 | 因为一旦两个变量都为空的时候,这个`rm`/`rmdir` 就变成了`rm -r /` or `rmdir -r /`。
21 | 4. 为了防止误删,你可以在`profile`里给`rm`或`rmdir`一个别名,比如:`alias rm='rm -i'`
22 | 5. 可以试试`safe-rm`来替代`rm`,用来防止误删。具体请参考[这里](https://manpages.ubuntu.com/manpages/focal/man1/safe-rm.1.html) -------------------------------------------------------------------------------- /linux/008-more.md: -------------------------------------------------------------------------------- 1 | # more: 翻页查看文件内容 2 | 前几天学习了使用`cat`命令查看Linux系统里文件的内容,但是有些时候一些文件文本过大,直接用`cat`很难阅读,我们更希望能够进入文本,在文本里一页一页或一行一行的查看,这时候`more`这个命令就派上了用场。 3 | 4 | ## 常用参数 5 | ``` 6 | 空格: 向下翻一页 7 | Enter: 向下翻一行 8 | /<字符串>: 向下搜寻<字符串>关键字 9 | :f 立即显示出文件以及目前显示的行数 10 | q: 代表立刻离开编辑页面 11 | b: 往回翻页 12 | ``` 13 | 14 | ## 使用场景 15 | 1. 一般来说,记着使用空格(Space)来翻页,或者回车键(Enter)来翻行,以及使用`/`加上你想要搜索的关键词来在全文搜索,和`q`退出,这些基本操作就够用了。 16 | -------------------------------------------------------------------------------- /linux/009-less.md: -------------------------------------------------------------------------------- 1 | # less: 翻页查看文件内容 2 | 上篇介绍了**more**,这篇介绍另一个类似的命令**less**。 3 | 4 | ## 常见参数 5 | ``` 6 | -N: 显示行号 7 | -p <关键字>: 以关键字为阅读的起始位置 8 | 9 | # 常见操作 10 | 空格:向下翻一页 11 | pagedown: 向下翻动一页 12 | pageup: 向上翻动一页 13 | /<字符串>: 向下搜寻<字符串>关键字 14 | ?<字符串>: 15 | n: 搜索下一个匹配关键字 16 | N: 反向搜索下一个匹配关键字 17 | g: 跳到第一行 18 | G: 跳到最后一行 19 | q: 退出 less 20 | 10g: 跳到第10行 21 | m <字符>: 插入书签 22 | ' <字符>: 跳转到所插入的书签 23 | ``` 24 | 25 | ## 使用场景 26 | 1. 相比起**more**,**less**更加灵活,可以上下文不同方向搜索。输入 **/**,然后输入要搜索的关键字,然后用**n**或**N**跳到下一个匹配的关键字。输入`?` 是往回搜索,如果你错过上一个关键字的话。 27 | 2. **less**书签标注功能是**more**没有的。比如,你读到第10行,你发现这个内容有用,你就可以按下**m**键,再输入任意以字母,比如**a**,来标识这一行。等你以后想要回来这行的时候,你只要按下`‘` (单引号),再输入相应的字母,这里的例子是**a**,你就可以快速跳转回之前标记的那一行了 28 | 3. 最后一个有用的功能是**F**,有点像**tail -f**,意思是,如果你阅读的是一个还在变化的文件,比如应用日志,按下**F**(大写F)之后文件就会进入等待模式,一有新的内容,就会事实显示出来,**debug的时候非常好用**,这样就不需要来回跳进跳出了。 29 | -------------------------------------------------------------------------------- /linux/README.md: -------------------------------------------------------------------------------- 1 | seq 1 100 | xargs -n1 -P100 curl --connect-timeout 5 -d 'client_id=test' -d 'client_secret=' -d 'username=' -d 'password=' -d 'grant_type=password' 'http://localhost:18080/realms/master/protocol/openid-connect/token' 2 | -------------------------------------------------------------------------------- /python/practice-together/001-introduction/README.md: -------------------------------------------------------------------------------- 1 | # 组团练Python第1期-破除“哑巴英语” 2 | 3 | 同学们好!在过去的29期班会里,我们一起学习了Python的大部分基础知识,包括了Python内置的数据类型,比如数字类型(整数,浮点,复数,布尔),容器类型(列表,元组,字典,集合),以及字符串类型;我们还学习了函数的相关知识,知道了如何通过函数的方式重复使用同一块代码,大大的简化了代码量,提高了代码利用率;还学习了如何使用Python读取文件以及使用Python里的异常处理机制来处理可能遇到的错误异常,从而增强代码的健壮性。 4 | 5 | 我们还差最后一个非常重要的概念没介绍,那就是类与对象(Class and Object)。在我看来,Python的类与对象这个功能,是它区别于诸如Bash Shell 这类脚本语言最大风分水岭,它将Python从程序式编程(Programmatic Programming)带入面向对象式编程(OOP,也就是Object-Oriented Programming)。 6 | 7 | 不过接下来的十几期班会我不打算介绍类与对象,我想和大家开始一起练练手,开始真正的上手敲敲代码。 8 | 9 | 我相信在过去的班会里,还是有很多同学只看了文章,没有实际上手操作。编程语言和学英语类似,你只读了课本的文章,却不上手练,很容易学成“哑巴英语”,即看似每个单词都会,但是遇到了需要英语对话的场合,整个人瞬间都懵了。编程里也是一样,看似每个知识点你都了解,但真正面对电脑键盘需要编一个程序的时候,你就会脑袋一片空白,不知道从何开始。 10 | 11 | 接下来的十几期班会我会和大家一起破除这个魔咒,我们也许做不成编程高手,但是起码能把过去十几期学到的内容通过代码表达出来,真正做到学以致用。 12 | 13 | 因此我们另起了一个班会系列:组团练Python,而不是学Python。 14 | 15 | 我的计划是,通过Hackerank网站的编程面试题来让大家慢慢熟悉使用这门语言。 16 | 17 | 在组团学第一期的时候我也提到过,之所以选择这个网站的面试题,是因为我打算去面试的公司就是用的它们的题库。所以,一举两得,既练习了Python,也准备了面试。还有就是在网站做题可以有及时反馈,可以知道自己做没做对。 18 | 19 | 完全没有编程经验的同学不用担心,我会先挑选最简单的题目和大家一起做。如果同学们有任何疑问,可以在群里说,希望有编程经验的同学也能够多多帮助初学的同学,发挥我们组团学习的优势,一起学习,一起进步! 20 | 21 | 好了,话不多说,那就让我们练起来吧! 22 | 23 | 今日练习: 24 | 完成以下练习 25 | https://www.hackerrank.com/challenges/solve-me-first/problem?isFullScreen=true 26 | 27 | 这题是要你编写一个函数solveMeFirst,函数的返回值是你输入的两个值的和。大部分代码已经写好了,只需要你把return写一下就好。写完后点击一下“Run Code”测试一下你的答案。如果没问题,再点击“Submit Code”,完成本次练习。以后的流程都是这样。大家可以开始熟悉一下啦! -------------------------------------------------------------------------------- /python/practice-together/002-simpleArraySum/simpleArraySum.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'simpleArraySum' function below. 11 | # 12 | # The function is expected to return an INTEGER. 13 | # The function accepts INTEGER_ARRAY ar as parameter. 14 | # 15 | 16 | def simpleArraySum(ar): 17 | return sum(ar) 18 | 19 | if __name__ == '__main__': 20 | fptr = open(os.environ['OUTPUT_PATH'], 'w') 21 | 22 | ar_count = int(input().strip()) 23 | 24 | ar = list(map(int, input().rstrip().split())) 25 | 26 | result = simpleArraySum(ar) 27 | 28 | fptr.write(str(result) + '\n') 29 | 30 | fptr.close() 31 | -------------------------------------------------------------------------------- /python/practice-together/002-simpleArraySum/simpleArraySum_2.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'simpleArraySum' function below. 11 | # 12 | # The function is expected to return an INTEGER. 13 | # The function accepts INTEGER_ARRAY ar as parameter. 14 | # 15 | 16 | def simpleArraySum(ar): 17 | ar_sum = 0 18 | for i in ar: 19 | ar_sum += i 20 | return ar_sum 21 | 22 | if __name__ == '__main__': 23 | fptr = open(os.environ['OUTPUT_PATH'], 'w') 24 | 25 | ar_count = int(input().strip()) 26 | 27 | ar = list(map(int, input().rstrip().split())) 28 | 29 | result = simpleArraySum(ar) 30 | 31 | fptr.write(str(result) + '\n') 32 | 33 | fptr.close() 34 | -------------------------------------------------------------------------------- /python/practice-together/003-compareTriplets/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/practice-together/003-compareTriplets/README.md -------------------------------------------------------------------------------- /python/practice-together/003-compareTriplets/compareTriplets.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'compareTriplets' function below. 11 | # 12 | # The function is expected to return an INTEGER_ARRAY. 13 | # The function accepts following parameters: 14 | # 1. INTEGER_ARRAY a 15 | # 2. INTEGER_ARRAY b 16 | # 17 | 18 | def compareTriplets(a, b): 19 | a_score = 0 20 | b_score = 0 21 | for i in range(len(a)): 22 | if a[i] > b[i]: 23 | a_score += 1 24 | elif a[i] < b[i]: 25 | b_score += 1 26 | return a_score, b_score 27 | 28 | if __name__ == '__main__': 29 | fptr = open(os.environ['OUTPUT_PATH'], 'w') 30 | 31 | a = list(map(int, input().rstrip().split())) 32 | 33 | b = list(map(int, input().rstrip().split())) 34 | 35 | result = compareTriplets(a, b) 36 | 37 | fptr.write(' '.join(map(str, result))) 38 | fptr.write('\n') 39 | 40 | fptr.close() 41 | -------------------------------------------------------------------------------- /python/practice-together/004-diagonalDifference/diagonalDifference.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'diagonalDifference' function below. 11 | # 12 | # The function is expected to return an INTEGER. 13 | # The function accepts 2D_INTEGER_ARRAY arr as parameter. 14 | # 15 | 16 | def diagonalDifference(arr): 17 | left_to_right_sum = 0 18 | right_to_left_sum = 0 19 | for i in range(len(arr)): 20 | left_to_right_sum += arr[i][i] 21 | right_to_left_sum += arr[i][len(arr) - i -1] 22 | return abs(left_to_right_sum - right_to_left_sum) 23 | 24 | 25 | if __name__ == '__main__': 26 | fptr = open(os.environ['OUTPUT_PATH'], 'w') 27 | 28 | n = int(input().strip()) 29 | 30 | arr = [] 31 | 32 | for _ in range(n): 33 | arr.append(list(map(int, input().rstrip().split()))) 34 | 35 | result = diagonalDifference(arr) 36 | 37 | fptr.write(str(result) + '\n') 38 | 39 | fptr.close() 40 | -------------------------------------------------------------------------------- /python/practice-together/005-plusMinus/plusMinus.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'plusMinus' function below. 11 | # 12 | # The function accepts INTEGER_ARRAY arr as parameter. 13 | # 14 | 15 | def plusMinus(arr): 16 | pos_num = 0 17 | neg_num = 0 18 | zero_num = 0 19 | for i in arr: 20 | if i > 0: 21 | pos_num += 1 22 | elif i < 0: 23 | neg_num += 1 24 | else: 25 | zero_num += 1 26 | pos_ratio = round(pos_num / len(arr), 6) 27 | neg_ratio = round(neg_num / len(arr), 6) 28 | zero_ratio = round(zero_num / len(arr), 6) 29 | print(pos_ratio) 30 | print(neg_ratio) 31 | print(zero_ratio) 32 | 33 | if __name__ == '__main__': 34 | n = int(input().strip()) 35 | 36 | arr = list(map(int, input().rstrip().split())) 37 | 38 | plusMinus(arr) 39 | -------------------------------------------------------------------------------- /python/practice-together/006-staircase/staircase.py: -------------------------------------------------------------------------------- 1 | # Staircase 2 | # https://www.hackerrank.com/challenges/staircase/problem?isFullScreen=true 3 | 4 | #!/bin/python3 5 | 6 | import math 7 | import os 8 | import random 9 | import re 10 | import sys 11 | 12 | # 13 | # Complete the 'staircase' function below. 14 | # 15 | # The function accepts INTEGER n as parameter. 16 | # 17 | 18 | def staircase(n): 19 | space = ' ' 20 | hashtag = '#' 21 | 22 | for i in range(1,n+1): 23 | print(f'{space * (n-i)}{hashtag * i}') 24 | 25 | if __name__ == '__main__': 26 | n = int(input().strip()) 27 | 28 | staircase(n) 29 | -------------------------------------------------------------------------------- /python/practice-together/007-miniMaxSum/miniMaxSum.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'miniMaxSum' function below. 11 | # 12 | # The function accepts INTEGER_ARRAY arr as parameter. 13 | # 14 | 15 | def miniMaxSum(arr): 16 | min_sum = sum(arr) - max(arr) 17 | max_sum = sum(arr) - min(arr) 18 | print(f'{min_sum} {max_sum}') 19 | 20 | if __name__ == '__main__': 21 | 22 | arr = list(map(int, input().rstrip().split())) 23 | 24 | miniMaxSum(arr) 25 | -------------------------------------------------------------------------------- /python/practice-together/007-miniMaxSum/miniMaxSum2.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'miniMaxSum' function below. 11 | # 12 | # The function accepts INTEGER_ARRAY arr as parameter. 13 | # 14 | 15 | def miniMaxSum(arr): 16 | sum = min = max = arr[0] 17 | for n in arr[1:]: 18 | if n < min: 19 | min = n 20 | elif n > max: 21 | max = n 22 | sum += n 23 | print(f"{sum-max} {sum-min}") 24 | 25 | if __name__ == '__main__': 26 | 27 | arr = list(map(int, input().rstrip().split())) 28 | 29 | miniMaxSum(arr) 30 | -------------------------------------------------------------------------------- /python/practice-together/008-birthdayCakeCandles/birthdayCakeCandles.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'birthdayCakeCandles' function below. 11 | # 12 | # The function is expected to return an INTEGER. 13 | # The function accepts INTEGER_ARRAY candles as parameter. 14 | # 15 | 16 | def birthdayCakeCandles(candles): 17 | candles.sort() 18 | tallest = candles[-1] 19 | return candles.count(tallest) 20 | 21 | if __name__ == '__main__': 22 | fptr = open(os.environ['OUTPUT_PATH'], 'w') 23 | 24 | candles_count = int(input().strip()) 25 | 26 | candles = list(map(int, input().rstrip().split())) 27 | 28 | result = birthdayCakeCandles(candles) 29 | 30 | fptr.write(str(result) + '\n') 31 | 32 | fptr.close() 33 | -------------------------------------------------------------------------------- /python/practice-together/008-birthdayCakeCandles/birthdayCakeCandles2.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'birthdayCakeCandles' function below. 11 | # 12 | # The function is expected to return an INTEGER. 13 | # The function accepts INTEGER_ARRAY candles as parameter. 14 | # 15 | 16 | def birthdayCakeCandles(candles): 17 | count = 1 18 | tallest = candles[0] 19 | for i in candles[1:]: 20 | if i == tallest: 21 | count += 1 22 | elif i > tallest: 23 | tallest = i 24 | count = 1 25 | return count 26 | 27 | if __name__ == '__main__': 28 | fptr = open(os.environ['OUTPUT_PATH'], 'w') 29 | 30 | candles_count = int(input().strip()) 31 | 32 | candles = list(map(int, input().rstrip().split())) 33 | 34 | result = birthdayCakeCandles(candles) 35 | 36 | fptr.write(str(result) + '\n') 37 | 38 | fptr.close() 39 | -------------------------------------------------------------------------------- /python/practice-together/009-timeConversion/timeConversion.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'gradingStudents' function below. 11 | # 12 | # The function is expected to return an INTEGER_ARRAY. 13 | # The function accepts INTEGER_ARRAY grades as parameter. 14 | # 15 | 16 | def gradingStudents(grades): 17 | grades_after_round = [] 18 | for i in grades: 19 | if i < 38: 20 | grades_after_round.append(i) 21 | elif 5 - i % 5 < 3: 22 | grades_after_round.append(i + 5 - i % 5) 23 | else: 24 | grades_after_round.append(i) 25 | return grades_after_round 26 | if __name__ == '__main__': 27 | fptr = open(os.environ['OUTPUT_PATH'], 'w') 28 | 29 | grades_count = int(input().strip()) 30 | 31 | grades = [] 32 | 33 | for _ in range(grades_count): 34 | grades_item = int(input().strip()) 35 | grades.append(grades_item) 36 | 37 | result = gradingStudents(grades) 38 | 39 | fptr.write('\n'.join(map(str, result))) 40 | fptr.write('\n') 41 | 42 | fptr.close() 43 | -------------------------------------------------------------------------------- /python/practice-together/010- gradingStudents/gradingStudents.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'timeConversion' function below. 11 | # 12 | # The function is expected to return a STRING. 13 | # The function accepts STRING s as parameter. 14 | # 15 | 16 | def timeConversion(s): 17 | AM_or_PM = s[-2:] 18 | hour = s[:2] 19 | if AM_or_PM == "AM": 20 | if hour == "12": 21 | s = "00" + s[2:-2] 22 | else: 23 | s = s[:-2] 24 | elif AM_or_PM == "PM": 25 | if hour == "12": 26 | s = "12" + s[2:-2] 27 | else: 28 | s = str(int(hour) + 12) + s[2:-2] 29 | return s 30 | 31 | if __name__ == '__main__': 32 | fptr = open(os.environ['OUTPUT_PATH'], 'w') 33 | 34 | s = input() 35 | 36 | result = timeConversion(s) 37 | 38 | fptr.write(result + '\n') 39 | 40 | fptr.close() 41 | -------------------------------------------------------------------------------- /python/practice-together/011-kangaroo/kangaroo.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'kangaroo' function below. 11 | # 12 | # The function is expected to return a STRING. 13 | # The function accepts following parameters: 14 | # 1. INTEGER x1 15 | # 2. INTEGER v1 16 | # 3. INTEGER x2 17 | # 4. INTEGER v2 18 | # 19 | 20 | def kangaroo(x1, v1, x2, v2): 21 | if x1 < x2 and v1 <= v2: 22 | return 'NO' 23 | elif x1 > x2 and v1 >= v2: 24 | return 'NO' 25 | elif (x1 - x2) % (v2 - v1) != 0: 26 | return 'NO' 27 | else: 28 | return 'YES' 29 | 30 | 31 | if __name__ == '__main__': 32 | fptr = open(os.environ['OUTPUT_PATH'], 'w') 33 | 34 | first_multiple_input = input().rstrip().split() 35 | 36 | x1 = int(first_multiple_input[0]) 37 | 38 | v1 = int(first_multiple_input[1]) 39 | 40 | x2 = int(first_multiple_input[2]) 41 | 42 | v2 = int(first_multiple_input[3]) 43 | 44 | result = kangaroo(x1, v1, x2, v2) 45 | 46 | fptr.write(result + '\n') 47 | 48 | fptr.close() 49 | -------------------------------------------------------------------------------- /python/practice-together/012-breakingRecords/breakingRecords.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'breakingRecords' function below. 11 | # 12 | # The function is expected to return an INTEGER_ARRAY. 13 | # The function accepts INTEGER_ARRAY scores as parameter. 14 | # 15 | 16 | def breakingRecords(scores): 17 | highest_record = scores[0] 18 | lowest_record = scores[0] 19 | count_break_highest = 0 20 | count_break_lowest = 0 21 | for i in range(1, len(scores)): 22 | if scores[i] > highest_record: 23 | highest_record = scores[i] 24 | count_break_highest += 1 25 | elif scores[i] < lowest_record: 26 | lowest_record = scores[i] 27 | count_break_lowest += 1 28 | return count_break_highest, count_break_lowest 29 | 30 | 31 | if __name__ == '__main__': 32 | fptr = open(os.environ['OUTPUT_PATH'], 'w') 33 | 34 | n = int(input().strip()) 35 | 36 | scores = list(map(int, input().rstrip().split())) 37 | 38 | result = breakingRecords(scores) 39 | 40 | fptr.write(' '.join(map(str, result))) 41 | fptr.write('\n') 42 | 43 | fptr.close() 44 | -------------------------------------------------------------------------------- /python/practice-together/013-betweenTwoSets/betweenTwoSets.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/practice-together/013-betweenTwoSets/betweenTwoSets.py -------------------------------------------------------------------------------- /python/practice-together/014-ArrayDS/reverseArray.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'reverseArray' function below. 11 | # 12 | # The function is expected to return an INTEGER_ARRAY. 13 | # The function accepts INTEGER_ARRAY a as parameter. 14 | # 15 | 16 | def reverseArray(a): 17 | return a[::-1] 18 | if __name__ == '__main__': 19 | fptr = open(os.environ['OUTPUT_PATH'], 'w') 20 | 21 | arr_count = int(input().strip()) 22 | 23 | arr = list(map(int, input().rstrip().split())) 24 | 25 | res = reverseArray(arr) 26 | 27 | fptr.write(' '.join(map(str, res))) 28 | fptr.write('\n') 29 | 30 | fptr.close() 31 | -------------------------------------------------------------------------------- /python/practice-together/015-2ArrayDS/hourglassSum.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | import math 4 | import os 5 | import random 6 | import re 7 | import sys 8 | 9 | # 10 | # Complete the 'hourglassSum' function below. 11 | # 12 | # The function is expected to return an INTEGER. 13 | # The function accepts 2D_INTEGER_ARRAY arr as parameter. 14 | # 15 | 16 | def hourglassSum(arr): 17 | largest_hourglass_sum = float('-inf') 18 | 19 | for i in range(len(arr) - 2): 20 | for j in range(len(arr[0]) - 2): 21 | top_hourglass_sum = arr[i][j] + arr[i][j+1] + arr[i][j+2] 22 | middle_hourglass_sum = arr[i+1][j+1] 23 | bottom_hourglass_sum = arr[i+2][j] + arr[i+2][j+1] + arr[i+2][j+2] 24 | if top_hourglass_sum + middle_hourglass_sum + bottom_hourglass_sum > largest_hourglass_sum: 25 | largest_hourglass_sum = top_hourglass_sum + middle_hourglass_sum + bottom_hourglass_sum 26 | return largest_hourglass_sum 27 | 28 | if __name__ == '__main__': 29 | fptr = open(os.environ['OUTPUT_PATH'], 'w') 30 | 31 | arr = [] 32 | 33 | for _ in range(6): 34 | arr.append(list(map(int, input().rstrip().split()))) 35 | 36 | result = hourglassSum(arr) 37 | 38 | fptr.write(str(result) + '\n') 39 | 40 | fptr.close() 41 | -------------------------------------------------------------------------------- /python/practice-together/016-LeftRotation/rotateLeft.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | # https://www.hackerrank.com/challenges/array-left-rotation/problem?isFullScreen=true 3 | 4 | import math 5 | import os 6 | import random 7 | import re 8 | import sys 9 | 10 | # 11 | # Complete the 'rotateLeft' function below. 12 | # 13 | # The function is expected to return an INTEGER_ARRAY. 14 | # The function accepts following parameters: 15 | # 1. INTEGER d 16 | # 2. INTEGER_ARRAY arr 17 | # 18 | 19 | def rotateLeft(d, arr): 20 | rotated_arr = arr[d:] + arr[:d] 21 | return rotated_arr 22 | 23 | if __name__ == '__main__': 24 | fptr = open(os.environ['OUTPUT_PATH'], 'w') 25 | 26 | first_multiple_input = input().rstrip().split() 27 | 28 | n = int(first_multiple_input[0]) 29 | 30 | d = int(first_multiple_input[1]) 31 | 32 | arr = list(map(int, input().rstrip().split())) 33 | 34 | result = rotateLeft(d, arr) 35 | 36 | fptr.write(' '.join(map(str, result))) 37 | fptr.write('\n') 38 | 39 | fptr.close() 40 | -------------------------------------------------------------------------------- /python/practice-together/017-PrintTheElementsOfALinkedList/printLinkedList.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | # https://www.hackerrank.com/challenges/print-the-elements-of-a-linked-list/problem?isFullScreen=true 4 | 5 | import math 6 | import os 7 | import random 8 | import re 9 | import sys 10 | 11 | class SinglyLinkedListNode: 12 | def __init__(self, node_data): 13 | self.data = node_data 14 | self.next = None 15 | 16 | class SinglyLinkedList: 17 | def __init__(self): 18 | self.head = None 19 | self.tail = None 20 | 21 | def insert_node(self, node_data): 22 | node = SinglyLinkedListNode(node_data) 23 | 24 | if not self.head: 25 | self.head = node 26 | else: 27 | self.tail.next = node 28 | 29 | 30 | self.tail = node 31 | 32 | # Complete the printLinkedList function below. 33 | 34 | # 35 | # For your reference: 36 | # 37 | # SinglyLinkedListNode: 38 | # int data 39 | # SinglyLinkedListNode next 40 | # 41 | # 42 | def printLinkedList(head): 43 | current = head 44 | while current is not None: 45 | print(current.data) 46 | current = current.next 47 | 48 | if __name__ == '__main__': 49 | llist_count = int(input()) 50 | 51 | llist = SinglyLinkedList() 52 | 53 | for _ in range(llist_count): 54 | llist_item = int(input()) 55 | llist.insert_node(llist_item) 56 | 57 | printLinkedList(llist.head) 58 | -------------------------------------------------------------------------------- /python/study-together/001-introduction/practice/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/study-together/001-introduction/practice/README.md -------------------------------------------------------------------------------- /python/study-together/002-reference/practice/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/study-together/002-reference/practice/README.md -------------------------------------------------------------------------------- /python/study-together/003-history/practice/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/study-together/003-history/practice/README.md -------------------------------------------------------------------------------- /python/study-together/004-installation/practice/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/study-together/004-installation/practice/README.md -------------------------------------------------------------------------------- /python/study-together/005-inputoutput/README.md: -------------------------------------------------------------------------------- 1 | # 组团学第5期班会-输出和输入 2 | 3 | 同学们好!欢迎大家继续我们的第5期不定期班会,一起来系统的学习Python。 4 | 5 | 本期学习内容:输出和输入(Input/Output or I/O) 6 | 7 | 如果你能顺利的完成上期布置的练习作业,那么说明你已经知道在Python中如何打印一些东西了。恭喜你,完成了Python编程的第一步! 8 | 9 | 我们知道,现代计算机是基于冯诺依曼结构开启了新的计算机系统结构,这个结构中最重要的两个环节就是输入和输出了。 10 | 11 | 我们通过诸如键盘鼠标这样的输入设备向计算机中输入指令,计算机运算之后,再借助诸如显示器终端来输出相对应的结果。编程就是这样一个过程,你通过键盘敲入代码,或者执行一个已经存在的文件,然后计算机按照输入的代码指令从存储中调出数据进行运算,然后通过屏幕把计算结果呈现给程序员。 12 | 13 | 在Python中,其中一个很重要的输出的方式用的是print()语句。它可以打印字符串(string),数字(number),变量(variable)。这些我们后面都会逐一介绍。这里我们先简要说一下。 14 | 15 | 打印字符串(string)的时候,我们通常使用单引号(‘ ‘)或者双引号(“ ”)将string括起来。比如print(“hello world”)或者print('hello world')都可以。 16 | 17 | 如果打印数字(number),无需任何符号,直接写数字就好。比如,print(10)或者可以做个运算print(10+6)。 18 | 19 | 关于打印变量,原本我是想这里提的,但是写的过程中越写越多,发现有点超字数了,所以就放到下一个班会再讲吧。 20 | 21 | 以上就是输出Output,接下来我们讲一下输入Input。 22 | 23 | Input很简单,用的就是input()语句。你需要知道的是,在input()里的括号可以包含字符串string,这会成为你输入的提示语,但它本身并不影响你的程序,所以你写啥,或者啥都不写都行。你可以直接把你的输入打印出来,比如print(input())。但更常见的是先把input赋值给一个变量variable,然后再print这个变量,下次讲变量的时候就可以看几个例子。 24 | 25 | 其他关于print和input的案例,请参考廖神的这篇文章:https://www.liaoxuefeng.com/wiki/1016959663602400/1017032074151456 26 | 27 | 这里我们最后再介绍一个知识点,就是以上两个语句print和input,我们称它为函数,并且是内置函数(build-in function),意思就是说,只要你安装了Python,它就自带这些函数,你任何时候都能使用,并且可以多次调用的。像这样的内置函数非常多,具体可以参考:https://docs.python.org/3/library/functions.html 28 | 29 | 至于什么是函数,你可以简单的理解为它是一段定义好的可重复使用的代码,具体介绍我们之后的班会会花很多时间来详细讲解,这里就不赘述了。 30 | 31 | 好了,今天的班会就到这里。我们下期见! 32 | 33 | 今日练习:在Replit网站上写一段程序,让电脑把你输入的任何信息打印三遍:比如你输入一个Hello ‘World’,程序就会打印三行 34 | Hello ‘World’ 35 | Hello ‘World’ 36 | Hello ‘World’ 37 | 38 | 鼓励大家完成练习后截图发群里打卡! 39 | 40 | -------------------------------------------------------------------------------- /python/study-together/005-inputoutput/practice/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/study-together/005-inputoutput/practice/README.md -------------------------------------------------------------------------------- /python/study-together/006-variables/practice/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/study-together/006-variables/practice/README.md -------------------------------------------------------------------------------- /python/study-together/007-basic/practice/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/study-together/007-basic/practice/README.md -------------------------------------------------------------------------------- /python/study-together/008-number1/practice/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/study-together/008-number1/practice/README.md -------------------------------------------------------------------------------- /python/study-together/009-number2/practice/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/study-together/009-number2/practice/README.md -------------------------------------------------------------------------------- /python/study-together/010-number3/practice/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/study-together/010-number3/practice/README.md -------------------------------------------------------------------------------- /python/study-together/011-string1/practice/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/study-together/011-string1/practice/README.md -------------------------------------------------------------------------------- /python/study-together/012-string2/practice/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/python/study-together/012-string2/practice/README.md -------------------------------------------------------------------------------- /python/study-together/013-string3/practice/README.md: -------------------------------------------------------------------------------- 1 | # 今日练习:随便找一篇英文文章,然后把逗号和句号都替换成空格,之后再用split把所有的单词提取出来。 2 | 3 | # 拓展练习:如果你已经有一定基础了,再进一步,请算出每个单词在文章里出现的频率吧。 -------------------------------------------------------------------------------- /python/study-together/013-string3/practice/chance-1.py: -------------------------------------------------------------------------------- 1 | text = """ 2 | Bash is the GNU Project's shell—the Bourne Again SHell. This is an sh-compatible shell that incorporates useful features from the Korn shell (ksh) and the C shell (csh). It is intended to conform to the IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools standard. It offers functional improvements over sh for both programming and interactive use. In addition, most sh scripts can be run by Bash without modification. 3 | """ 4 | 5 | words = text.replace(",", " ").replace(".", " ").split() 6 | print(words) 7 | 8 | words_dict = {} 9 | 10 | for w in words: 11 | words_dict[w] = words.count(w) 12 | 13 | for w in set(words): 14 | print(f"There are {words_dict[w]} {w} in the text") -------------------------------------------------------------------------------- /script.sh.template: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Reference: 3 | # [set](https://gist.github.com/mohanpedala/1e2ff5661761d3abd0385e8223e16425) 4 | # [$*}(https://gist.github.com/mohanpedala/1e2ff5661761d3abd0385e8223e16425) 5 | 6 | 7 | # shellcheck disable=SC1091 8 | set -o errexit 9 | set -o nounset 10 | set -o pipefail 11 | # set -o xtrace # Uncomment this line for debugging purposes 12 | 13 | # Load libraries 14 | #. /opt/bitnami/scripts/libjenkins.sh 15 | #. /opt/bitnami/scripts/libfs.sh 16 | #. /opt/bitnami/scripts/libos.sh 17 | 18 | # Load Jenkins environment 19 | . /opt/bitnami/scripts/jenkins-env.sh 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /study-diary/2023/07/20230711: -------------------------------------------------------------------------------- 1 | # 开始日拱一卒啦 2 | 今天开始尝试着每天写点自己当天学习到的新知识,以督促自己每日学习。
3 | 4 | 1. 开始尝试知识星球,感觉这个相比于微信群,更适合群组讨论,这样讨论的知识才能沉淀。 5 | 2. Akamai是一家美国上市公司,主要经营CDN, 网络安全,和云服务。这两天被要求从我们的CRM软件里导出数据,然后注入到Akamai的数据库里,其中需要用到Azure的Data Factory, Storage Account, Function, Key Vault, Role Assignment等服务。这是一个很好的了解Terraform部署的机会,之后打算写一个类似的项目放入我们实验里。 6 | 3. ADF的部署挺有意思,基础的Instance可以使用IaC工具部署,比如Terraform或Azure ARM,但是之后的具体设置,你可以通过Azure portal UI来配置,配置完以后可以把相关配置Publish到Git的Branch里。UI和Source Control完美结合。 7 | 4. 看了一部很有意思的电视剧,Netflix《人选之人-造浪者》。一共8集,讲的是台湾大选期间各党派内部竞选活动,感觉挺真实,也挺温馨。一群人为了一个共同的目标一起在一段时间共同奋斗,是一段很美好的回忆。推荐 -------------------------------------------------------------------------------- /study-diary/2023/07/20230712.md: -------------------------------------------------------------------------------- 1 | 1. 复习一下Linux里`more`的命令用法:https://github.com/chance2021/devopsdaydayup/blob/main/linux/008-more.md 2 | 2. 昨天Microsoft把**Azure AD (AAD)** 改名了,改成了 **Microsoft Entra ID** 。除了名字之外其他所有的服务都没变。详情可以参考:https://azure.microsoft.com/en-us/updates/azure-ad-is-becoming-microsoft-entra-id/#:~:text=Microsoft%20Entra%20ID%20is%20the,secure%20access%20experiences%20for%20everyone. 3 | 3. Microsoft的**Dev Box**进入了稳定版本(GA)。你可以用每个月订阅制或者用多少花多少钱的方式使用,它提供16或32 Core CPU。这次正式发布还引入了休眠模式(**hibernate**),不用关机,直接挂机就好,等下次登入后会回到你上次离开的地方。详情可以参考:https://azure.microsoft.com/en-us/updates/microsoft-dev-box-is-now-generally-available/ 4 | 4. 还是关于**Dev Box**,我的理解,这就是一个远程可供开发使用的**高性能**服务器。之所以重点**高性能**,是因为如果你的本地电脑够用,其实也不需要它。只有当你需要很强的算力,比如一些做大数据的开发,才需要用到这么一台远程高性能的电脑。你可以通过远程登入的方式,登入到Dev Box,然后再进行开发。这台服务器会提前把你需要使用到的工具都安装好。而且,因为它在Azure network里,你还可以和你在Azure上的一些资源直接连接,比如Azure的数据库。 -------------------------------------------------------------------------------- /study-diary/2023/07/20230713.md: -------------------------------------------------------------------------------- 1 | 今天迭代一版日志,分个类,目前暂定分为三类。第一类是**项目更新**,这个项目主要指的是**DevOpsDayDayUp的DevOps学习项目**,目前包括小项目实验,大项目实验,Azure学习和Linux学习。第二类是**技术新闻**,每天挑选一两个有意思的技术新闻和大家分享。第三类是**随便聊聊**,大杂烩,看到什么有意思的都随手分享,不限题材。那么开始吧! 2 | 3 | # 【项目更新】 4 | 1. 一起学习一下**Azure PIM**。有些公司会用,要了解的内容不多,但是你得知道有这么一个东西,并且如何使用:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230712-IAM-PIM.md 5 | 2. 最近在准备一个小项目实验,主要是**使用Terraform部署Azure资源**,有可能是Function或者Data Factory,到时候看情况吧。这次使用的Terraform和之前有所不同,这次会着重**使用Module来控制传递的变量**。并且有一些HCL的很有意思的用法,比如dynamic。 6 | 7 | # 【技术新闻】 8 | 1. **马斯克成立一个AI公司,叫做xAI**,里面三分之一是华人,还有多伦多大学学者。成立当天还不忘嘲讽一下扎克伯格,在推特上发了一个真假蜘蛛侠的图片,暗讽前几天”抄袭“推特的Threads。 9 | 2. 还是马斯克的新闻,今天特斯拉弄了一个新产品,是一个**针对儿童的玩具摩托车**,车子设计的很拉风,有点像沙滩摩托车,售价1900美元。看来马斯克已经开始向未成年人下手了... ref: https://cyberquad.store/ 10 | 3. **阿里巴巴取消P序列职位层级**,改为14-28层级。P8,或者说28级基本就是天花板了,以上不会有职级,直接由组织任命,薪酬和业务规模或团队项目范围挂钩。 11 | 12 | # 【随便聊聊】 13 | 这几天参加了古典的读写训练营,学习了**卡片读书法**,方法就是在看一本书的时候,如果遇到哪些让你非常有启发的文字,使用四个部分把它梳理遍,第一部是**原文摘要**,把原文摘抄下来;第二部分是**概念转述**,也就是用你的话把这段文字复述一遍;第三部分是**个人体验**,使用你已有的知识和经验和文字相关联,让书本的文字和你产生联系;第四部分是**行动指南**,也就是总结出一个Action Item,你之后想要做什么事来改变你的某些习惯。知识不是力量,习惯才是力量。 14 | -------------------------------------------------------------------------------- /study-diary/2023/07/20230714.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第4天 2 | 3 | 又到了一周工作日的最后一天,回顾一下,这周最大的收获还是Azure+Terraform得部署学习。当一个公司环境有非常多的时候,如何合理的进行规划非常重要,包括Terraform的TF文件结构如何设计,每个resource的资源名字如何命名,还有Terraform state数量和范围如何把控(如果更新资源过多,每次更新一个小调整都需要terraform plan一个小时的时间,那就需要考虑拆分)。每个公司只要业务不断增长,最终都会面临这个问题,需要提前做一些准备。 4 | 5 | # 【项目更新】 6 | 1. 学习一下Linux里另一个查看文件的命令**less**: https://github.com/chance2021/devopsdaydayup/blob/main/linux/009-less.md 7 | 2. Azure+Terraform的实验今天又推进了一点,module写的有点复杂,写了两个,第一个Module是本地Module, 它会调用第二个Module,第二个Module模拟的是云端Module。这样开发人员就负责本地的Module修改,云端的Module就完全由SRE/DevOps团队负责,全责分离。 8 | 9 | ## 【科技新鲜事】 10 | 1. 昨天说的特斯拉推出的儿童玩具车,今天在中国官网正式上线后,由于访问人数过多,网站直接瘫了,有些黄牛直接加价到6万RMB(原价11990 RMB)...看来感兴趣大龄儿童太多了... 11 | 2. 另一个马斯克的产品推特Twitter已经开始将广告收益分享给创作者了。看来老马还是比较通人性的,知道人都是趋利的,能通过一个稳定的收入锁定一些头部KOL,才能锁定流量。不知道扎克伯格的Threads知道以后会不会跟上效仿。可以官网。 12 | 3. 京东言犀大模型正式推出。AI已经成为了每个大公司必备的产品了。上个月美团的王兴出手收购了他的好兄弟王慧文的AI公司光年之外,不知道现在进展如何了。 13 | 14 | ## 【随便聊聊】 15 | 周五了,借花献佛,给做大数据的同学们送上一波免费的课程。大家周末快乐! 16 | 17 | 🔸 学习Excel(12天) 18 | 📚 教程:lnkd.in/eWmC2vf8 19 | 🛠️ 项目:lnkd.in/ew5y5KP7 20 | 21 | 🔹 学习基础统计学(3天) 22 | 📚 教程:lnkd.in/emKawHBs 23 | 24 | 🔸 学习Power BI(20天) 25 | 📚 教程:bit.ly/npowerbi 26 | 🛠️ 项目:bit.ly/3Xjpn0v 27 | 28 | 🔹 学习SQL(20天) 29 | 📚 教程:lnkd.in/epAFJzJB 30 | 🛠️ 项目:lnkd.in/eq9jqcBq 31 | 32 | 🔸 学习Python(20天) 33 | 📚 教程:lnkd.in/eh4gTQQ2 34 | 🛠️ 项目:lnkd.in/emzcrzTX 35 | 36 | 🔹 在项目中工作并构建你的数据分析作品集(15天) 37 | 📚 作品集:lnkd.in/eVFWpmFg 38 | 🛠️ 项目:lnkd.in/epd_9Bx8 39 | 40 | 🔸 构建简历并准备应聘数据分析岗位 41 | 🛠️ 简历:lnkd.in/eAaTiiJi 42 | -------------------------------------------------------------------------------- /study-diary/2023/07/20230717.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第5天 2 | 又是新的一周! 3 | 4 | # 【项目更新】 5 | 1. 大家来了解一下**Microsoft Intune**吧:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230717-IAM-Intune.md 6 | 2. 今天又花了半天弄Terraform module,但是一直出错,前后总共弄了三天都没弄好,我放弃了,看来步子跨的太大了,接下会改用简单的Module使用方法,目的是了解Azure Function如何部署就好,至于之后如何更好的使用Module,等再学习一下再重新开始做吧。Terraform的水还是有点深。 7 | 8 | # 【科技新鲜事】 9 | 1. 携程集团发布首个旅游行业垂直大模型“携程问道”。看来AI开始对旅游行业下手了。话说,如果旅游数据够多,不知道导游这行业是不是就不复存在了? 10 | 2. 好莱坞十万多人大罢工,抗议制片公司和流媒体平台的不公平待遇和AI的威胁。这让我想起了若干年前网约车刚刚进入市场的时候,出租车司机的大罢工。如今的出租车司机谁还没注册个Uber滴滴账户呢? 11 | 3. 马斯克表示xAI将采用推特的公开推文训练。前几天推特限制了非蓝标用户每天刷推量,也是为了防止其他第三方使用推特的数据。话说,这些数据能用来做什么呢?来对一个进行人格分析?还是设计一些安全相关的模型?不懂 12 | 13 | 14 | # 【随便聊聊】 15 | 古典老师给迷茫的同学支了一招,他说,如果你经常性的迷茫,本质是不知道如何把一个虚无缥缈的大目标切的足够细。比如说,有些同学想写作,很迷茫的坐在那里想:“我该写点啥?“其实如果把它变成说,如何写一个文章的标题,可能就没这么难了;或者想想,前面十个字能写点啥,那你就更容易能开始动笔了。对人生很迷茫的同学,你可以换个角度想想,比如:”我今天上午做些什么,能够让我自己晚上睡的踏实“。也许你会有不同的感触和想法。解决焦虑最好的方法就是,马上动手解决一个小事。 -------------------------------------------------------------------------------- /study-diary/2023/07/20230718.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第6天 2 | 3 | ## 【项目更新】 4 | 1. 本来想讲讲**Entitlement management**和**Microsoft Entra Identity Governance**,但是发现这个好像大部分用户都不需要知道,考试也不咋考,那就提一下名字直接跳过吧。今天我们来讲一个Azure里最重要的概念**Resource Management**。使用Azure的同学这些知识点一定要知道了: https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230718-ARM-ResourceManagement.md 5 | 2. 关于Azure + Terraform的那个问题,昨天本来是打算放弃的,想着使用最简单的方法实现就好。但是今天上午又有一点灵感,打算步子迈的小一点,先实现一个简单的Working instance,在弄复杂的。如果这个还是不行,就需要找同学帮帮忙,一起Share Screen看看吧。熟悉Terraform的同学麻烦课后联系我一下哈 谢谢! 6 | 7 | ## 【科技新鲜事】 8 | 1. 第一条又是马斯克的新闻。特斯拉首款Cybertruck生产完成。截止2022年11月,Cybertruck的预定量超过150万。看着图片里炫酷的卡车外形,还真有点期待不久的将来在大街上一睹真容,想想也是应该会非常拉风的吧 9 | 2. 拼多多旗下的Temu在美国起诉Shein,质控Shein利用市场支配力量强迫服装产商与之签订独家协议,违反美国反垄断法。其实去年12月Shein也曾将Temu告上南伊利诺伊州地方法院,质控它有诱导网红发表贬低公司的言论,并采用“冒名顶替”的方法误导用户认为两个平台存在联系,最终诱导用户下载Temu。哎,只能说,本是同根生,相煎何太急... 10 | 3. 小米计划在印度开更多线下店。这几年小米在印度的市场份额被三星反超了,看来雷总坐不住了。 11 | 12 | ## 【随便聊聊】 13 | 分享几条OpenAI创始人山姆.奥特曼的人生信条: 14 | 1. 朋友家人和那些对你重要的人永远都不要降低优先级。 15 | 2. 有几个知己胜过一百个熟人。 16 | 3. 别跟老朋友失联,偶尔和友人通宵长谈,必不可少。 17 | 4. 生活不是彩排,认真的过好每一天,人生苦短,光阴飞逝,做一些自己喜欢做的事情,想做就去做,别给自己留借口。 18 | 5. 跟那些能帮助你的人建立关系,努力工作,锻炼识人的能力。 19 | -------------------------------------------------------------------------------- /study-diary/2023/07/20230720.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第8天 2 | 3 | ## 【项目更新】 4 | 1. 再更新了一下昨天的Azure+Terraform项目,做了两个更新:一个是`naming_standards.tf`更新了一下,这个主要是用来统一**命令规范**;还有一个更新是关于**backend_modules**里面的`tags`,多了一个`default_tags`,主要是把一些标准变量以**tags**的形式存储,比如**environment**, **project_name**, **instance_name**等等。tags用的好可以在统计Cost的时候方便归类查询。 5 | 2. 今天我们来学习一下Azure用户最常用的资源:**Azure Virtual Machine**。今天文章有点点长,文末有关于**如何阅读VM型号**的小贴士哦: https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230720-Compute-VM.md 6 | 7 | ## 【新鲜事】 8 | 1. 美团入股中文大模型公司智谱AI。看来美团对AI很重视啊。不过之前不是说已经收购了好兄弟王慧文的AI公司了吗?也不知道进展的如何了 9 | 2. 马斯克继续上榜。。近日特斯拉正式向美国和加拿大地区推出新的“Charge on Solar"(太阳能充电)功能,让特斯拉车主可以只使用太阳能为自己的电动汽车充电。这个功能很酷啊!马斯克在他的火星移民计划又前进了一步 10 | 3. 苹果被曝正在秘密研究AI工具,基于这个名为”Ajax"的平台,苹果还推出了一款聊天机器人服务。苹果终于下场了! 11 | 4. 又一个和AI相关的新闻,就是麦肯锡宣布与AI公司Cohere合作,为客户提供人工智能解决方案。 12 | 5. OpenAI也没闲着,与美国地方新闻机构合作,用AI技术辅助地方新闻事业。AI正在逐渐渗入你我的日常生活当中了 13 | 14 | ## 【随便聊聊】 15 | 古典老师分享了他想对10年前的自己说的10句话: 16 | 1. 远离那些会让你掉头发伤身体的工作,在专业管理方面选择一条至少让你能做10年的工作 17 | 2. 不要有侥幸心理,如果一个行业不行了,就是不行了,请尽快离开 18 | 3. 花点时间处理好3种关系:第一个是和父母的关系,因为他们会越来越需要你,第二个是跟你自己小家庭的关系,因为你必然要投入越来越多,第三个是跟钱的关系,因为你会越来越需要它 19 | 4. 你没法模仿牛人,你也没法成为完人,你要做的事就是把自己的优势发挥到极致 20 | 5. 别再迷信成功学了,你应该早就发现所有的成功都没法复制 21 | 6. 不要因为自己不够成熟就害怕要一个孩子,你可以跟孩子一起长大 22 | 7. 没有必要让所有人都喜欢你,但是你必须要让几个人特别的爱你 23 | 8. 不要丢掉你的好奇心,不要丢掉你身体里面的小男孩或者小女孩 24 | 9. 少参加那些攀比型的同学会,因为你们貌似起点一致,其实你们根本就是起点不同,路径也不同,你没有必要成为他们的谈资 25 | 10. 如果有时间,多读一点哲学,宗教,人文和艺术的东西,因为这些东西是穿越时代的,不管生活有多乱,不管生活有什么变化,你总得有一点坚信的东西。 26 | 27 | 对10年的自己说,不要慌,不要怕,慢慢走,以自己为中心走,一步步的往前走,10年后的你远远比你想象的要精彩太多 -------------------------------------------------------------------------------- /study-diary/2023/07/20230721.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第9天 2 | 3 | ## 【项目更新】 4 | 1. Azure+Terraform正式移进了大项目(cicdpipeline里),之后会继续更新Azure的一些主要Resource的部署,其中包括:keyvault, app service, aks, role assignment, data factory,等。 5 | 2. 今天来学习一个使用Azure VM后有可能会使用到的服务:**Azure Bastion**。它和平常的Bastion Machine(堡垒机)可不太一样,具体请参考:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230721-Compute-AzureBastion.md 6 | 7 | ## 【新鲜事】 8 | 1. Google联合创始人谢尔盖.布林重回公司,专注新AI系统研发工作。应了那句话:AI没整好,小命都不保... 9 | 2. 华为云自动驾驶开发平台正式发布,看来华为要比苹果更早向汽车领域发力了。 10 | 3. 世界头号黑客凯文.米特尼克(Kevin David Mitnick)确认于2023年7月16日去世,享年59岁。凯文出生于1963年8月6日,是美国计算机安全顾问,作家和黑客。他16岁因破解太平洋电信公司密码,在付费电话系统中修改上万美国家庭的电话号码,而被电脑信息跟踪机个跟踪逮捕,因此成为了全球第一名网络少年犯。出狱后,他有成功入侵了诺基亚、摩托罗拉、升阳以及富士通等公司的计算机,盗取企业重要资料,FBI曾统计他给这些公司带来的损失高达4亿美元。 11 | 4. 特斯拉大举投资马来西亚快速充电站网络。蔚来近期也发布了他自己的充电桩,并于祁连山国家公园共同构建全球首个V2G光伏自循环补能体系,将于8月份投入使用。看来电动车的势头已经势不可挡了 12 | 13 | ## 【随便聊聊】 14 | 昨天分享了古典老师给35岁自己的10个建议,今天再来听听刘润老师给35岁年轻人的建议吧: 15 | 1. 不要轻易去听老年人的人生建议 16 | 2. 老年人之所以称为老年人,是因为ta体内的多巴胺分泌和新陈代谢都开始下降了,ta体会不到学习新鲜事物带来的这种乐趣 17 | 3. 一个真正的老年人,ta会慢慢体悟出来一个人生哲理:平平淡淡才是真 18 | 4. 你只能听取老年人的人生经验,但是不要听取ta的人生建议。这个人生经验包括ta犯过的错误。 19 | 5. 判断自己老没老的最重要的标准是:你还愿不愿意尝试新的东西。只要你有探索的愿望,你的心就还没老 20 | 6. 永远保持探索,永远保持开放的心态 -------------------------------------------------------------------------------- /study-diary/2023/07/20230724.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第10天 2 | 日拱一卒上两位数了。时间过得真快啊 3 | 4 | ## 【项目更新】 5 | 1. 大项目里Terraform+Azure的Storage account创建已经基本完毕,这次创建覆盖了基本上Azure Storage Account的所有属性,建议同学们有机会可以去看看。 6 | 2. 今天来学习一下AKS: https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230724-Compute-AKS.md 7 | 3. 顺便再啰嗦一下,咱们的Azure学习基本框架已经出来了,一条线是基础理论知识的学习,我们会把Azure基本资源全面的过一遍,同时,另一条线结合我们的Azure+Terraform实验,更细致的了解这些Resource的属性,通过Terraform部署来验证我们的理解是否正确。关于Azure Compute部分的学习,我们会按照IaaS->PaaS->SaaS/FaaS的顺序来讲,方便大家层层递进的去理解它的演化过程。 8 | 9 | 10 | ## 【新鲜事】 11 | 1. 马斯克又双叒叕上头条了。。马斯克宣布他将更换他购买的推特的Twitter的图标(小蓝鸟),更换为他最喜欢的字母X。其实去年,马斯克收购了推特公司就将公司改名为“X公司”。然后2017年的时候,他还花了500万美元,从前公司Paypal那里买了x.com这个域名。有钱人就是想法不一样啊 12 | 2. 除了改商标,马斯克在推特上发文称,他想把推特改造成超级App,有点类似我们的微信。拭目以待吧 13 | 3. 当地之间7月21日,包括谷歌、微软、OpenAI、亚马逊、Meta、Anthropic、Inflection在内的七家顶级人工智能公司的在白宫召开会议,承诺姜维消费者创建识别生成式人工智能的方法,并且确保在生成式人工智能工具发布前,会测试其安全性。之前从OpenAI离职,创建Claude AI的兄妹俩Daniela和Dario就是因为安全性的问题,从OpenAI离职出来单独干的。也不知道这个会议能起到多大的效果。祝福人类吧 14 | 4. 欧洲汽车制造商协会表示,今年前四个月,欧洲30个国家共售出的电动汽车超过了燃油车。特斯拉Model Y是上半年欧洲全品类销量最高车型。 15 | 16 | ## 【随便聊聊】 17 | 今天听了一期井户端,嘉宾奶茶讲了一句话很有感触:“只有成功的人才相信努力。”。这和之前听到的一句话类似:“失败不是成功之母,成功才是成功之母。”能给你成功经验的只有成功本身,失败只能让你避坑,不一定能帮你成功。所以年轻的时候,尽量去发挥自己的优势,创造一两个属于自己的成功案例,然后就容易粘贴了。 -------------------------------------------------------------------------------- /study-diary/2023/07/20230726.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第11天 2 | 不好意思同学们,昨天跳票了,主要是被老板拉去加班加到了快晚上十二点,完全没时间。。 今天争取多补几条新鲜事弥补一下吧。 3 | 4 | ## 【项目更新】 5 | 1. 不知道ACI是什么的同学快看过来:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230726-Compute-ACI.md 6 | 2. 大项目更新了一些Azure Key Vault相关的部署。不过老实说,Key Vault难的不是部署,而是如何让不同的服务和其相连。这个以后遇到具体案例再和大家分享。 7 | 3. 今天学习到了一个使用Azure Function的方法,就是通过Portal里的Bash服务直接访问Function的相关日志。这个对于Troubleshoot Function服务来说相当重要。之后讲到Function的时候会和大家分享一下 8 | 9 | ## 【新鲜事】 10 | 1. ChatGPT安卓版正式上线,可惜只能在美国印度孟加拉国和巴西四个国家使用。扯开话题,前几天看了一个记录孟加拉国生活的纪录片,介绍了一个“淘金”的工种,画面有点可怕,就不描述了,不适合吃饭时候看。感兴趣的朋友可以自己搜索"Documentary: Per capita income of $100 per month, the nost stressful place to live in Asia!" 11 | 2. 理想汽车新增车辆“睡眠辅助系统”专利。说这个,主要是想说,现在国内的电动汽车制造汽车的观念,已经从一个出行工具,转向第二生活场景了。舒适度方面国内的车企还是比较有竞争力的。 12 | 3. TFBOYS十年之约演唱会开始线上售票。知道这个信息,可以让你年轻十岁 :) 13 | 4. C-Eval 中文大模型权威排名公布,前四分别是清华智谱的ChatGLM2, OpenAI的GPT-4,商汤的Sense-Chat, 和APUS的AlLMe-100Bv1。 14 | 5. OpenAI创始人山姆.奥特曼耗时三年,联合创立的Web3加密项目世界币(WorldCoin)前几天正式启动。这个数字货币由保护隐私的数字身份(World ID)和数字货币WLD组成,在法律允许的情况下,仅有人类可以获得。消息一出,世界币WLD的价格就飙升了90%,达到3.34美元。奥特曼的想法很简单,就是以后AI和机器人足够发达之后,人类就不需要工作了,直接领钱享受生活就好。这不禁让我想起了黑客帝国里的场景... 15 | 16 | ## 【随便聊聊】 17 | 分享一个段古典老师关于理解的不同层度解释: 18 | 第一级:理解字面意思 19 | 第二级:可以给别人用自己的话复述 20 | 第三级:区分和其他类似事情的不同之处 21 | 第四级:可以传授给别人,让别人也能理解 22 | 第五级:应用到工作生活中 23 | 第六级:能迁移到其他领域 24 | 第七级:不知道自己知道,变成自己的肌肉记忆 25 | 26 | 我希望我对云的学习也能按照这个等级走。先是理解每个专业名词的含义,然后可以讲给别人听,之后再学习AWS和Google的云产品后能知道它们之间的优缺点,之后能形成一个完整的课程体系交付给大家,当然最重要的是能把这些学到的知识运用到工作中,帮助团队做决策,解决问题。最后变成自己的肌肉记忆,不用想就能脱口而出。这是我追求的境界。继续努力吧! -------------------------------------------------------------------------------- /study-diary/2023/07/20230727.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第12天 2 | 今天东南沿海刮台风了,希望福建的小伙伴们能平安度过。 3 | 4 | ## 【项目更新】 5 | 1. 昨天学了ACI, 今天学习ACR, 两个可以配套服用:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230727-Compute-ACR.md 6 | 2. Azure+Terraform的项目还在Keyvault这一块Troubleshooting。 争取明年弄好,下一个就可以弄Function了。 7 | 8 | ## 【新鲜事】 9 | 1. 美联储宣布加息25个几点,上调到5.25%-5.50%,利率达到22年最高水平。据说加拿大这回不跟了,也不知道真的假的。 10 | 2. 网易有道退出国内首个教育领域垂直大模型“子曰”,并发布了基于“子曰”大模型研发的六大创新应用:LLM翻译,虚拟人口语教练,AI作文指导,语法精讲,AI Box以及文档问答 11 | 3. 华为鸿蒙4.0将于8月4日正式发布。没用过,据说可以像Apple生态一样随意转换设备。有机会可以体验的一下 12 | 13 | ## 【随便聊聊】 14 | 今天看了纪念耗子叔的直播,其中CSDN创始人蒋涛讲的一句话让我停下来思考了一下。他说:“AI的出现,替代了程序员90%的能力,但是却放大了10%的能力。这个10%的能力包括:定义真实问题的能力,分解问题的能力,解决问题的能力以及设计产品架构的能力”。随着AI技术的出现,编程能力越来越被边缘话了。原因很简单,就是现在AI能通过你的描述就能给你可执行的代码,那编程能力还有什么用吗?但是哪怕AI再厉害,也得你问它问题,它才能给你答案。如果你的问题问错了,那它也无法解决你的真实问题。那下一个问题就是,如何能问出真实的问题呢?不知道,我也在思考吧。大家有什么想法也可以一起分享一下吧 -------------------------------------------------------------------------------- /study-diary/2023/07/20230728.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第13天 2 | 又到周五了,又是一周。2023年已经过去一半了,你敢信吗? 3 | 4 | ## 【项目更新】 5 | 1. 如果你想部署网站,但是又不太熟悉容器,那么你可以试试Azure的App Serivce:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230728-Compute-AppService.md 6 | 2. Azure+Terraform项目还是停留在Key Vault部署,主要是Varaible太多,比较费时间。我的想法是,这个Key Vault弄完,大项目先放一放。我想多做一些小项目。然后选择几个大家比较感兴趣的话题再开一个班会。话说上次开班会好像是上个月的事情了吧。。。 7 | 8 | ## 【新鲜事】 9 | 1. 洪涛将入职百川智能。洪涛是当年搜狗三剑客,另外两个一个是老板王小川,一个是茹立云。百川智能是王小川拉了之前搜狗的很多前同事一起做出的人工智能服务公司,旨在打造中国版的OpenAI基础大模型以及颠覆性的上层应用,今年4月份才成立的,已经获得了5000万美元启动资金。不知道这次曾经的计算机神童王小川是否能再打造继搜狗之后的明星产品。 10 | 2. 微信偷偷模仿小红书,推出了小绿书。看了一下操作界面,不能说很像吧,简直就是一模一样!看来这几年小红书的发展势头已经让腾讯忌惮了。腾讯继续搬出了它的复制粘贴大法,想用它的高流量和多用户来挤占小红书的市场。回头看,腾讯推出的视频号确实抢占了抖音快手的一部分流量。但是小绿书的出现是否也能在小红书这里分一杯羹呢?我觉得不容易。这得看它的推荐算法够不够先进了。还有一个点,就是小红书的用户普遍都比较积极阳光(因为是女生多的原因?),这个用户庞大的腾讯是否反而变成劣势?我们拭目以待吧 11 | 3. Google、微软、OpenAI等联手组建AI行业组织,目的是确保前沿AI以安全、负责任的方式发展。有时候想想,这些企业真挺好的,能冲在前面替我们思考这么多风险隐患。无论他们最终目的如何,都值得尊敬。 12 | 13 | ## 【随便聊聊】 14 | 周末了,分享一些轻松的话题吧,最近关注一个Youtube博主XIAOHAN 小涵哥,感觉还挺不错。主要介绍一些历史上的奇闻轶事,比如神奇的印度阅兵,韩国青瓦台事件,还有最近的泰坦号事件。作为茶余饭后的娱乐资讯读读也挺有意思的。这周就这样了。祝大家周末愉!我们下周见! -------------------------------------------------------------------------------- /study-diary/2023/07/20230731.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第14天 2 | 3 | 国内多地水灾,希望大家都平安。 4 | 5 | ## 【项目更新】 6 | 1. 给上周的App Service做一个扩展,补充一个很重要的概念:App Service Plan。这个在之后的Azure Function上也会提到,算是预习了: https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230729-Compute-AppServicePlan.md 7 | 2. Azure+Terraform的大项目没太多进展,还在收尾阶段。这个一结束,打算开始准备Azure第一个小项目实验,关于Azure Function。可以结合之后的文章一起学习 8 | 9 | ## 【新鲜事】 10 | 1. 这两天最热门的新闻就是韩国研究人员声称发现常压室温超导材料这个事了。先不考虑这个事是否是真的(虽然目前的信息显示概率不高,不过还是希望是真的吧),我们来看看如果这个实验成功,世界讲发生哪些巨大变化:第一个,电力获取成本低到忽略不计,想用多少电,就用多少电,还不用担心污染环境;第二个,磁悬浮列车普及,每小时1000公里的速度,让你可以缩短至少三倍的旅程时间;第三个:医疗成像技术显著提高,诊断可靠性和安全性大大加强,人类又向百岁人生迈进了一步;第四个,手机电脑电池续航时间加强,一年充一次电都有可能,只要你不要看太多视频玩太多游戏就好,信号也更强了,速度更快,容量更大,功耗更低。如果这个实验真的实现了,那么第四次工业革命就可以开始了。期待后续发展吧 11 | 2. Twitter已经改名字和Logo了,小蓝鸟飞走了,随之而来的是一个黑不溜秋的X,还没适应过来。马斯克为了让用户不流失,最近宣布了他的“广告收益共享计划”,该计划的目标是向第一轮满足要求的创作者发放500万美元,据说已经有人收到了一万甚至十几万的回报,不知是真是假,但是Twitter这个月的月活跃度达到了新高,5.4亿,也许这能从侧面证明一下。和他形成反差的是近期Meta的扎克伯格表示它们的Threads用户活跃度好像越来越少了,看来Twitter还是占据了一些先发优势。 12 | 3. Meta的Threads不行,但是元宇宙服务却又新发展。Meta长期开发的VR元宇宙服务“地平线世界”的移动版本可能很快就会推出。据说这个游戏体验比其他平台上大多数游戏体验都好,因为它使用了从外部导入的对象,资源和纹理构建。至于什么意思,我也不知道,非VR玩家,没有发言权。 13 | 4. Google的DeepMind宣布推出了RT-2:全球第一个控制机器人的视觉-语言-动作(VLA)模型。这个模型可以让机器人不需要复杂的命令,就和ChatGPT一样简单容易操作。不知道看到这个消息,马斯克是不是对他的机器人有什么想法了。 14 | 5. 还是马斯克的消息,上周马斯克的SpaceX成功发射全球最大的商业通信微信“木星三号”,此次发射是SpaceX今年第51次发射,也是猎鹰系列火箭第250次成功发射。虽然网络越来越发达,但是还是希望别破坏环境吧。如果黑夜里只能看到卫星却看不到星星,有点让人沮丧。 15 | 16 | ## 【随便聊聊】 17 | 没啥聊的,该聊的上面的都聊过了。以后没什么可聊的就冥想5分钟。冥想去啦 -------------------------------------------------------------------------------- /study-diary/2023/08/20230801.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第15天 2 | 3 | 进入八月份了,貌似多伦多的夏天已经过去了,据说卡尔加里都已经下过冰雹了? 4 | 5 | ## 【项目更新】 6 | 1. Microsoft自己研发的类似Kubernetes的平台了解一下?Azure Service Fabric: https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230731-Compute-AzureServiceFabric.md 7 | 2. 今天开始准备Azure Function的实验了。这次实验的目的是通过Terraform部署Azure Function。其中涉及到两个部署,一个是Function App本身的部署,还有一个是使用Azure DevOps Pipeline来发布你的Code到Function App里的Function上。如果效果好,计划策划一期班会和大家一起过一遍。 8 | 9 | ## 【新鲜事】 10 | 1. 华中科技大学材料学院博士后武浩在同事和导师的协助下,全程直播复现了韩国的室温常压超导实验。它烧出了一小块LK99晶体,并复现了磁悬浮现象,基本上验证了迈斯纳效应,也就是部分证明了韩国人的超导实验其中一部分的真实性。但是这次烧出来的晶体只有一小块,还没有进一步做电阻测试,所以还不能算完全证明这个实验成功。看来人类又多了一线希望了 11 | 2. 特斯拉旗下Model3, Model Y多款型号在中国香港将于8月4日再次降价。看来马老板完全忽视前段时间其他几个汽车产商关于不降价的倡议了。 12 | 3. 刚刚在推特上看到马斯克秀出了特斯拉制造的手机,据说可以连他的卫星网络。如果是真的,那这个手机就厉害了。 13 | 4. 还是马斯克的新闻,最近他投资的电动飞行汽车初创公司Alef Aeronautics表示,公司收到了2500份预定订单。预计将于2025年在美国空中飞行。滴滴飞行要来了 14 | 5. Cohere宣布扩大与亚马逊云科技的合作,其AI基础模型在Amazon Bedrock上可以使用。这是一项完全托管的服务,让用户能够通过API访问经过预训练的基础模型,从而构建、部署和管理AI解决方案。 15 | 16 | ## 【随便聊聊】 17 | 分享推上看到的两个保持精力旺盛的方法: 18 | 1. 降低自己的兴奋度,心情尽量不要大起大落。比如,少打游戏、少看短视频,以减少不必要的多巴胺分泌。学会深呼吸,日常锻炼至少30分钟 19 | 2. 有目标,知道自己想要什么,知道自己应该干什么,知道自己这样做会带来怎么样的收益。每天感受自己的进步和对世界认知的扩张。 20 | 21 | 养成以上两种习惯,你会发现除非重大事件发生,你每天都会处于一种小快乐、小幸福的状态,对探索和进步的欲望会很高,做什么都有动力和效率,不会有疲惫感和萎靡感。 22 | 23 | 有时候也在想,如果超导研究成功,那世界将会非常不一样,也许人类真的可以不用再工作了。那个时候,活着的意义也许是每个人最需要知道的事情。 -------------------------------------------------------------------------------- /study-diary/2023/08/20230802.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第16天 2 | 3 | 室温超导三部曲:“杀疯了,赢麻了,emo了” 4 | 5 | 6 | ## 【项目更新】 7 | 8 | 1. 今天介绍一个看名字就知道是做什么的服务: **Azure Static Web App**:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230801-Compute-AzureStaticWebApp.md 9 | 10 | 2. Terraform部署Azure Function的小项目已经完成一半,成功的使用Terraform部署了Function App。接下来需要使用Azure DevOps Pipeline来部署更新Function到Function App上。Pipeline写好了,但是跑的时候报错,好像是我使用的Pipeline task不能用来部署当前的Function app deployment。还需要再看看问题的具体原因。 11 | 12 | 13 | ## 【新鲜事】 14 | 1. 韩国室温常压超导的事情又有了新进展。该研究团队成员表示,论文存在缺陷,系团队中的一名成员擅自发布,目前团队已要求下架论文。但这也不能说明这个实验完全没有意义,因为这一事件会使得未来几年里在这个方向上做研究的科学家越来越多,也就是说未来的成功率就会越来越高。未来还是依旧可期的 15 | 16 | 2. 俄罗斯国立研究型大学莫斯科电子技术学院科研人员,使用激光脉冲代替光刻开发出了一种为信息显示设备创建元件的新技术。这将加速降低下一代显示器和各种光学系统超表面的生产成本。 17 | 18 | 3. 多个AIGC应用在苹果应用商店下架,主要因为8月15日即将施行的《生成式人工智能服务管理暂行办法》,下架的App在数据采集和使用环节等不够规范,重新商家需要一段时日。看来超导的冷水也冲向了AI领域了 19 | 20 | 4. 谷歌助手正在转向生成式人工智能。不知道苹果的Siri啥时候能升级 21 | 22 | ## 【随便聊聊】 23 | 最近几年的科技发展太快了,AI、超导、Web3、量子计算、核聚变。。据说未来的5年内会有重大科技突破。当下的我们能做的也许只有一件事了:锻炼好身体,至少活到那个时候。不说了,锻炼去了... 24 | -------------------------------------------------------------------------------- /study-diary/2023/08/20230803.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第17天 2 | 3 | ## 【项目进展】 4 | 5 | 1. 又是一个看了名字就知道做什么的Azure服务:**Azure Spring Apps** -> https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230802-Compute-AzureSpringApps.md 6 | 7 | 2. 今天一天都在部署Function,手动成功了,但是Pipeline发布死活不成功。只能明天继续Troubleshooting了。 8 | 9 | 10 | ## 【新鲜事】 11 | 12 | 1. 美国癌症机构研发出能消灭所有实体瘤的神奇靶向药。虽然只是刚刚进入临床一期,但是真的是肿瘤患者们的福音。超导落空了,这个突破也可以啊 13 | 14 | 2. 瑞幸营收首次超过星巴克中国,成为中国市场第一家门店数量突破万家的连锁咖啡品牌。这家公司也是厉害,居然能从之前的财务造假风波中走出来,而且还是越走越好。 15 | 16 | 3. 马斯克说,特斯拉年底有望实现完全自动驾驶。老马怎么天天都有新闻? 17 | 18 | 4. 阿里云开眼通义前问70亿参数模型,包括通用模型Qwen-7B和对话模型Qwen-7B-Chat,两款均已上线魔搭社区,开源、免费、可商用。这使得阿里云成为国内首个加入大模型开源行列的大型科技企业。 19 | 20 | 5. 腾讯也不示弱,它们自研的”腾讯混元大模型“已经进入应用自测阶段。AI还在迅猛发展啊 21 | 22 | 23 | ## 【随便聊聊】 24 | 这两天弄的Function部署有点emo了,在想是不是我的方法不对呢?或者说,云计算到底要怎么学习?很好奇那些云计算大神的学习之路到底是怎么走的... -------------------------------------------------------------------------------- /study-diary/2023/08/20230804.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第18天 2 | 3 | 一眨眼,一周就过去了... 4 | 5 | ## 【项目更新】 6 | 1. 终于开始介绍这几天折磨我的项目了:**Azure Function** -> https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230803-Compute-AzureFunctions.md 7 | 2. 实验16(Terraform+Azure Function+Azure DevOps pipeline)还是卡在了部署阶段。现在卡住的问题是,我的电脑不支持Azure Function task 的python upload。说是不支持ARM64架估计得换一台Linux的电脑了。 8 | 9 | ## 【新鲜事】 10 | 1. Uber正在开发一款AI聊天机器人,它的竞争对手DoorDash也正在构建它自己的聊天机器人DashAI。以后如果点餐不需要自己想,和AI对话,让它帮我决定,也是个好事。 11 | 2. 华为正式发布HarmonyOS 4操作系统,并首次将AI大模型技术落地在华为多个系统应用上。期待华为用户的反馈。 12 | 3. 苹果版“余额宝”已吸纳100亿美元存款。手上有那么多现金,怎么花是个很大的问题。 13 | 14 | ## 【随便聊聊】 15 | 下两周家里有事,估计要停更一段时间。最近几篇Azure阅读量很低,估计是内容还不够具体?没办法,我也刚刚开始学,还没有太多Best Practice的经验可以结合分享。先快速把所有名词过一遍,第二遍再考虑如何能输出更有价值的内容吧。 -------------------------------------------------------------------------------- /study-diary/2023/08/20230821.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第19天 2 | 3 | 不好意思,由于最近太忙,放了两周的鸽子。这周重新开始更新。 4 | 5 | ## 【项目更新】 6 | 1. 如果你不会编程但是又想做一个自动化工作流,**Azure Logic App** 可以了解一下: https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230821-Compute-AzureLogicApp.md 7 | 8 | 2. 实验16(Terraform+Azure Function+Azure DevOps pipeline),没啥进展。还是那个问题,我的电脑不支持Azure Function task 的python upload。说是不支持ARM64架估计得换一台Linux的电脑了,这个可能得暂停一下。 9 | 10 | 3. 近期有打算再开一个班会,内容是分享vim的使用经验,估计是下周,正在筹划中。 11 | 12 | 4. 最近开通了小红书,主要是和大家聊一聊找工作的经验分享。感兴趣的同学可以一起来讨论。小红书搜索:devopschance 13 | 14 | ## 【新鲜事】 15 | 1. 8月20日, Adobe官网宣布Adobe公司联合创始人John Warnock于当地时间8月19日去世,享年82岁。John与Charles Geschke于1982年共同创立了Adobe,并担任首席执行官至2000年,担任首席技术官至2001年退休。此后,它们两人共担任董事会主席,直至2017年,其后一直担任董事会成员。它们与1982年凭借PostScript创立了Adobe, 引发了桌面出版革命。说到Adobe,突然联想到近期发现的Edge浏览器的画板功能超级好用,可以用来在电脑上签字的。有时候Adobe这个功能需要收费,Edge就可以很好的派上用场。 16 | 17 | 2. 福特将在加拿大魁北克省内投资8,9亿美元建设电动汽车电池工厂,这个项目将创建345个工作岗位机会。魁北克的同学有机会了。 18 | 19 | 3. 字节跳动大模型对话产品”豆包“开放测试,用户可以通过网页或者下载App体验。这个产品具备自然语言处理、知识回答、语言翻译、文本摘要、情感分析等功能,在展示案例里可以生成健身计划,心理学书籍,奇幻小说开头等。看了这么多大模型,大家都具备的功能都包括翻译,看来翻译这行真的快被AI蚕食殆尽了。 20 | 21 | 4. 稚晖君创业公司智元机器人发布了第一款产品人性机器人”远征A1"。 稚晖君本名彭志辉,2020年加入“华为天才少年计划”,负责华为昇腾计算产品产品线的全栈研发。此前,彭志辉就职于OPPO研究院AI实验室。2022年12月彭志辉发帖表示将离开华为,投身机器人创业项目。智元机器人成立三个月后边完成了第三轮融资,估值超过10亿美元。随着老龄化的加剧,人形机器人市场前景还很不错啊。 22 | 23 | ## 【随便聊聊】 24 | 出门散步锻炼身体了。 -------------------------------------------------------------------------------- /study-diary/2023/08/20230822.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第20天 2 | 3 | 4 | ## 【项目更新】 5 | 1. Azure里的HPC服务了解一下**Azure Batch**:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230822-Compute-AzureBatch.md 6 | 7 | 2. Vim分享的PPT已经开始准备了,这次打算采用陈浩老师翻译的一篇文章的结构来说,也就是分成了三个级别:存活下来,感受良好,更好更快更强,手把手的带着大家从0开始学习Vim。 8 | 9 | 3. 昨天小红书更新了一篇介绍如何进行HR电话面试的文章,欢迎大家交流讨论。 10 | 11 | ## 【新鲜事】 12 | 1. 软银旗下的芯片设计公司ARM向美国证交会提交IPO申请,有望成为今年美国交易所最大规模的IPO交易,并可能成为有史以来美国规模最大的科技发行交易之一。不知道这一把孙正义是否能把在WeWork身上亏的钱一次性都赚回来。 13 | 14 | 2. 英国监管机构批准博通619亿美元收购VMWare。之前做服务器运维的时候VMware的虚拟机使用的多,现在做DevOps以后接触最多的VMware产品可能就是Tanzu了。 15 | 16 | 3. 因事故频发,加州宣布正式对无人出租车公司Cruise进行调查。不知道国内百度的无人车运行的如何。如果这个试点成功,那出租车出行费用应该会大大降低吧。 17 | 18 | 4. 世纪互联宣布Skype国内将在今年10月1日停止服务,由Microsoft Teams取代。Skype对我来说就是打电话用的,通信谁还用它。 19 | 20 | ## 【随便聊聊】 21 | 蛀牙坏了,约了牙医,出门了,明天见 -------------------------------------------------------------------------------- /study-diary/2023/08/20230824.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第21天 2 | 提醒一下,昨天Microsoft Azure的diagnostic settings storage retention退役了,转成了Azure Storage lifecycle management。 如果有同学使用到这个功能,需要马上做一些迁移,否则就会报错。具体迁移流程参见下面链接: 3 | https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/migrate-to-azure-storage-lifecycle-policy 4 | 5 | ## 【项目更新】 6 | 1. 不知道AVS是啥奇葩Azure服务的同学们请看这个:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230824-Compute-AzureVMwareSolution.md 7 | 8 | 2. Vim班会PPT初稿已经完成。接下来会在8月31日晚上7点30分(多伦多时间)和大家在线分享。大家到时候见! 9 | 10 | 11 | ## 【新鲜事】 12 | 1. 日本宣布8月24日起将核污染水排海,240天到达中国,1200天扩散到北太平洋范围。无语了 13 | 2. 外媒爆料,小米汽车利润率仅为1%, 主要是通过软件或车机系统创收。据说已经确定了中创新航和宁德时代作为电池供应商。预计2024年上半年正式开始量产。对小米的产品还是挺期待的。 14 | 3. iPhone15顶配机型有望首次搭载潜望式镜头,据说焦变能力从前代的3倍提升至5-6倍。这个以后拍远距离物体就更清晰了。现在手机性能真的是日新月异。 15 | 16 | ## 【随便聊聊】 17 | 今天才知道,我们公司IT部门每天早上10点-11点都有一个线上会议,任何人如果有问题都可以加入提问,没问题就忽略。会议里被提到的问题都会当场处理或者加急。个人感觉这个用户体验很好,有问题不超过24小时就能被马上解决或起码被推动一下,这个被在Service Now提交Ticket或者Chat里文字问问题体验好多了,值得所有服务类型的部门借鉴。 -------------------------------------------------------------------------------- /study-diary/2023/08/20230825.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第22天 2 | 3 | 4 | ## 【项目更新】 5 | 1. 不知道AVS是啥奇葩Azure服务的同学们请看这个:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230824-Compute-AzureVMwareSolution.md 6 | 7 | 2. 第37次班会将在8月31日晚上7点30分(多伦多时间)开始,大家不见不散! 8 | 9 | 10 | ## 【新鲜事】 11 | 1. 有消息称微软把PYthon 弄进Excel里了。微软通过和数据科学平台Anaconda合作实现了Python实现了Python in Excel, 用户数据可视化的Matplotlib和seaborn等等,今后无需任何配置,在单元格里输入"=PY",就能使用Python,数据清理、预测分析、可视化等任务都能轻松实现。Python之父在X上表示很高兴,3年前加入微软的时候做梦也没想到这会成真。微软在技术上的投入是认真的。 12 | 2. Meta正式计划推出一款帮助开发人员自动生成代码的软件,名为Code Llama。Github的Copilot有竞品了。 13 | 3. 英伟达2024财年第二季度营收达历史新高。英伟达的显卡现在和黄金有一拼了。 14 | 15 | ## 【随便聊聊】 16 | 又落枕了 休息去了 lol -------------------------------------------------------------------------------- /study-diary/2023/08/20230830.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第23天 2 | 3 | ## 【项目更新】 4 | 1. 今天群里刚好聊到腾讯云的竞价实例,那我们就来了解一下Azure的对应产品,Azure Spot VM: https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230830-Compute-AzureSpotVM.md 5 | 6 | 2. 第37次班会将在明天晚上7点30分(多伦多时间8月31日)开始,同学们不见不散! 7 | 8 | 9 | ## 【新鲜事】 10 | 1. 苹果宣布将于北京时间9月13日凌晨1点举行2023年秋季发布会。据说充电线接口这次全部换成USB-C了,变焦也从3倍变成了5倍,电池容量也有所提升,还支持35w有线闪充。好像还没看到什么爆点。不过看了看空空的钱包,微笑着表示还好没钱,要不然差点被骗了。 11 | 12 | 2. OpenAI宣布推出企业版ChatGPT,该版本拥有增强的安全性、隐私性和一系列为企业量身定制的强大功能。我们公司虽然能上ChatGPT,但是IT不建议上,很多银行直接屏蔽了他们的网站。但是面对这么强大的武器,不用的公司一定会落伍的。 13 | 14 | 3. 华为Mate 60 Pro正式上线,这是全球首款支持卫星通话的大众智能手机。好奇它如何计费的。 15 | 16 | 4. 百度文心一言向全社会开放,用户可以在应用商店下载“文心一言APP“或者登入"文心一言官网”体验。此外,百度还将开放一批经过全新重构的AI原生应用,让广大用户充分体验生成式AI的理解、生成、逻辑、记忆四大核心能力。没用过,不过好奇“车水马龙"是否还能被画出来。 17 | 18 | 5. 美图公司旗下AI数字人生成工具DreamAvator上线,首期推出"AI演员”数字人服务,以AI驱动为核心,服务于视频内容创作、影视处理与剪辑等生产力场景。AI正在让视频创作的成本越来越低。 19 | 20 | ## 【随便聊聊】 21 | 听了一本书,叫做《刻意专注》,主要是让我们重新认识“注意力”这个我们唯一能掌控的宝贵资源。注意力系统有三种,第一种是定向系统,它就像手电筒一样,聚光;第二种是警觉系统,它像泛光灯一样对周围的变化随时做出反应;第三种是执行功能,它能感知你的感知,这也是我们通常所说的元认知。破坏注意力的因素有压力,不良情绪和威胁。注意力的对手是走神。所以,最好的锻炼注意力的方法是正念冥想,温柔的把自己每一次走神拉回到呼吸上,经常观察自己脑袋里的思想,还有就是可以经常扫描自己身体,让你的身体和心灵链接。 -------------------------------------------------------------------------------- /study-diary/2023/08/20230831.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第24天 2 | 3 | ## 【项目更新】 4 | 1. 第37次班会将在今天晚上7点30分(多伦多时间8月31日)开始,同学们不见不散! 5 | 6 | 7 | ## 【新鲜事】 8 | 1. 谷歌云与英伟达宣布扩大合作伙伴关系以推进AI计算、软件和服务的发展。虽然不好用,但是还在继续努力。 9 | 2. 谷歌宣布将于10月4日举行秋季发布会,预计推出Pixel 8/Pixel 8 Pro/Pixel Watch。有可能推出Pixel Buds A系列和Pro系列。对标苹果。 10 | 3. Synthetaic 与微软达成为期5年战略合作,微软将为Synthetaic提供近100万小时云计算资源。我们公司最近也和微软签了一个好几年的合作协议。主要是微软的全家桶太全了,脱离成本好高。 11 | 12 | ## 【随便聊聊】 13 | 古典老师分享了一个他在《认知觉醒》这本书里提到的一个提高自律的方法:早冥读写跑。它们分别是:早起,冥想,读书,写作,跑步。早起让你拥有足够多属于自己的空间和时间,跑步来提高你的精力值,冥想让你的情绪更稳定,读书是内容的输入,写作是内容的输出。在自己可控的时间和空间里,用充沛的体能和良好的心情,让知识在你的身体进进出出,坚持一个月,一定会见到效果。 -------------------------------------------------------------------------------- /study-diary/2023/09/20230907.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第25天 2 | 3 | ## 【项目更新】 4 | 1. 这周开始进入对Azure Virtual Network的学习: https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230904-Network-AzureVirtualNetwork.md 5 | 2. 关于Azure Network的学习,除了Azure的Network相关产品,我更想和大家一起学习的是关于Network本身的理论知识学习。那第一篇就必须是IP了:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230906-Network-IP.md2. 6 | 7 | ## 【新鲜事】 8 | 1. 小米汽车已经试生产近一个月,每周生产50辆。看来小米玩真的了。 9 | 2. 阿里云推出视频生成大模型,用于短视频内容生产、电影制作等场景。很快我们就能看到完全由AI创造的短视频了(刘润最近的视频是不是都是AI制作的?) 10 | 3. OpenAI官宣将在今年11月6日于旧金山举行首届开发者大会。奥特曼继续发力。 11 | 12 | ## 【随便聊聊】 13 | 要上班了,没空聊了。下次说吧 -------------------------------------------------------------------------------- /study-diary/2023/09/20230910.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第26天 2 | 3 | ## 【项目更新】 4 | 1. 说完IP,不得不提DNS。今天我会把DNS访问的全部流程和大家梳理一遍:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230908-Network-DNS.md 5 | 6 | ## 【新鲜事】 7 | ## 【随便聊聊】 8 | 太晚了,要睡觉去了,大家晚安! -------------------------------------------------------------------------------- /study-diary/2023/09/20230912.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第27天 2 | 3 | ## 【项目更新】 4 | 1. 介绍一下网络中和IP齐名的另一个重磅概念:TCP https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230911-Network-TCP.md 5 | 6 | ## 【新鲜事】 7 | 1.特斯拉用于训练自动驾驶汽车人工智能模型的超级计算机Dojo可能会为其带来“不对称优势“,并使其市值增加近6000亿美元,增长幅度达76%,摩根士丹利将其股票评级从“持股观望”上调至“增持股份”。话说马斯克的自传已经出来了,期待。 8 | 2.Meta正在开发一种新的人工智能系统,对标OpenAI开发的ChatGPT。人工智能赛道依旧火热。 9 | 3.阿里巴巴CEO兼董事长张勇卸任,由吴泳铭接任,并宣布阿里两大战略重心:用户为先、AI驱动。所有的业务根基使用户价值以及带来的用户留存。看看新CEO对日渐疲态的阿里是否能起到力挽狂澜的作用。 10 | 11 | ## 【随便聊聊】 12 | 今天听了一个播客,讲到内耗分为两种,一种是事的内容,一种是人的内耗。事的内耗=欲望-行动。你可以通过减少欲望或者增强行动来减少内耗。人的内耗=猜测-沟通。少一些猜测,多一些公开通明的沟通,能减少人之间的内耗。 -------------------------------------------------------------------------------- /study-diary/2023/09/20230914.md: -------------------------------------------------------------------------------- 1 | # 日拱一卒第28天 2 | 3 | ## 【项目更新】 4 | 1. 网络理论的基石,我曾经的面试题:OSI七层理论:https://github.com/chance2021/devopsdaydayup/blob/main/cloud/azure/20230912-Network-OSI.md 5 | 6 | ## 【新鲜事】 7 | 1.马斯克在All-InPodcast2023峰会上谈到特斯拉的FSD(全自动驾驶)系统,表示FSD已经超越了人类司机的安全性,而且非常接近现实无需监督或干预的自动驾驶。自动驾驶时代马上要开启了。
8 | 2.SpaceX星链曲边收入14亿,是2021年的近6倍。之后的手机再支持卫星电话,这个收入不得翻倍吗?
9 | 3.Adobe宣布AI应用Firefly全面商用。看了一段视频,就是你可以用这个软件,在一张照片上画一个圈,然后文字输入你想要出现的画面,比如湖景,然后软件就会在这个照片的这个圈里不违和的加入一个湖,很厉害。 10 | 11 | ## 【随便聊聊】 12 | 又发现一个很好的播客《脑放电波》,很有洞见的IT牛人。 -------------------------------------------------------------------------------- /tmp/keyvault-issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chance2021/devopsdaydayup/514b25cee900a3deff63cc95bd461b08435e627f/tmp/keyvault-issue.png --------------------------------------------------------------------------------