CINXE.COM

Compositions · Crossplane v1.18

<!doctype html><html lang=en class=color-toggle-hidden color-theme=light><head><meta charset=utf-8><script type="text/javascript"> ;window.NREUM||(NREUM={});NREUM.init={distributed_tracing:{enabled:true},privacy:{cookies_enabled:true},ajax:{deny_list:["bam.nr-data.net"]}}; window.NREUM||(NREUM={}),__nr_require=function(t,e,n){function r(n){if(!e[n]){var o=e[n]={exports:{}};t[n][0].call(o.exports,function(e){var o=t[n][1][e];return r(o||e)},o,o.exports)}return e[n].exports}if("function"==typeof __nr_require)return __nr_require;for(var o=0;o<n.length;o++)r(n[o]);return r}({1:[function(t,e,n){function r(t){try{s.console&&console.log(t)}catch(e){}}var o,i=t("ee"),a=t(32),s={};try{o=localStorage.getItem("__nr_flags").split(","),console&&"function"==typeof console.log&&(s.console=!0,o.indexOf("dev")!==-1&&(s.dev=!0),o.indexOf("nr_dev")!==-1&&(s.nrDev=!0))}catch(c){}s.nrDev&&i.on("internal-error",function(t){r(t.stack)}),s.dev&&i.on("fn-err",function(t,e,n){r(n.stack)}),s.dev&&(r("NR AGENT IN DEVELOPMENT MODE"),r("flags: "+a(s,function(t,e){return t}).join(", ")))},{}],2:[function(t,e,n){function r(t,e,n,r,s){try{l?l-=1:o(s||new UncaughtException(t,e,n),!0)}catch(f){try{i("ierr",[f,c.now(),!0])}catch(d){}}return"function"==typeof u&&u.apply(this,a(arguments))}function UncaughtException(t,e,n){this.message=t||"Uncaught error with no additional information",this.sourceURL=e,this.line=n}function o(t,e){var n=e?null:c.now();i("err",[t,n])}var i=t("handle"),a=t(33),s=t("ee"),c=t("loader"),f=t("gos"),u=window.onerror,d=!1,p="nr@seenError";if(!c.disabled){var l=0;c.features.err=!0,t(1),window.onerror=r;try{throw new Error}catch(h){"stack"in h&&(t(14),t(13),"addEventListener"in window&&t(7),c.xhrWrappable&&t(15),d=!0)}s.on("fn-start",function(t,e,n){d&&(l+=1)}),s.on("fn-err",function(t,e,n){d&&!n[p]&&(f(n,p,function(){return!0}),this.thrown=!0,o(n))}),s.on("fn-end",function(){d&&!this.thrown&&l>0&&(l-=1)}),s.on("internal-error",function(t){i("ierr",[t,c.now(),!0])})}},{}],3:[function(t,e,n){var r=t("loader");r.disabled||(r.features.ins=!0)},{}],4:[function(t,e,n){function r(){U++,L=g.hash,this[u]=y.now()}function o(){U--,g.hash!==L&&i(0,!0);var t=y.now();this[h]=~~this[h]+t-this[u],this[d]=t}function i(t,e){E.emit("newURL",[""+g,e])}function a(t,e){t.on(e,function(){this[e]=y.now()})}var s="-start",c="-end",f="-body",u="fn"+s,d="fn"+c,p="cb"+s,l="cb"+c,h="jsTime",m="fetch",v="addEventListener",w=window,g=w.location,y=t("loader");if(w[v]&&y.xhrWrappable&&!y.disabled){var x=t(11),b=t(12),E=t(9),R=t(7),O=t(14),T=t(8),P=t(15),S=t(10),M=t("ee"),N=M.get("tracer"),C=t(23);t(17),y.features.spa=!0;var L,U=0;M.on(u,r),b.on(p,r),S.on(p,r),M.on(d,o),b.on(l,o),S.on(l,o),M.buffer([u,d,"xhr-resolved"]),R.buffer([u]),O.buffer(["setTimeout"+c,"clearTimeout"+s,u]),P.buffer([u,"new-xhr","send-xhr"+s]),T.buffer([m+s,m+"-done",m+f+s,m+f+c]),E.buffer(["newURL"]),x.buffer([u]),b.buffer(["propagate",p,l,"executor-err","resolve"+s]),N.buffer([u,"no-"+u]),S.buffer(["new-jsonp","cb-start","jsonp-error","jsonp-end"]),a(T,m+s),a(T,m+"-done"),a(S,"new-jsonp"),a(S,"jsonp-end"),a(S,"cb-start"),E.on("pushState-end",i),E.on("replaceState-end",i),w[v]("hashchange",i,C(!0)),w[v]("load",i,C(!0)),w[v]("popstate",function(){i(0,U>1)},C(!0))}},{}],5:[function(t,e,n){function r(){var t=new PerformanceObserver(function(t,e){var n=t.getEntries();s(v,[n])});try{t.observe({entryTypes:["resource"]})}catch(e){}}function o(t){if(s(v,[window.performance.getEntriesByType(w)]),window.performance["c"+p])try{window.performance[h](m,o,!1)}catch(t){}else try{window.performance[h]("webkit"+m,o,!1)}catch(t){}}function i(t){}if(window.performance&&window.performance.timing&&window.performance.getEntriesByType){var a=t("ee"),s=t("handle"),c=t(14),f=t(13),u=t(6),d=t(23),p="learResourceTimings",l="addEventListener",h="removeEventListener",m="resourcetimingbufferfull",v="bstResource",w="resource",g="-start",y="-end",x="fn"+g,b="fn"+y,E="bstTimer",R="pushState",O=t("loader");if(!O.disabled){O.features.stn=!0,t(9),"addEventListener"in window&&t(7);var T=NREUM.o.EV;a.on(x,function(t,e){var n=t[0];n instanceof T&&(this.bstStart=O.now())}),a.on(b,function(t,e){var n=t[0];n instanceof T&&s("bst",[n,e,this.bstStart,O.now()])}),c.on(x,function(t,e,n){this.bstStart=O.now(),this.bstType=n}),c.on(b,function(t,e){s(E,[e,this.bstStart,O.now(),this.bstType])}),f.on(x,function(){this.bstStart=O.now()}),f.on(b,function(t,e){s(E,[e,this.bstStart,O.now(),"requestAnimationFrame"])}),a.on(R+g,function(t){this.time=O.now(),this.startPath=location.pathname+location.hash}),a.on(R+y,function(t){s("bstHist",[location.pathname+location.hash,this.startPath,this.time])}),u()?(s(v,[window.performance.getEntriesByType("resource")]),r()):l in window.performance&&(window.performance["c"+p]?window.performance[l](m,o,d(!1)):window.performance[l]("webkit"+m,o,d(!1))),document[l]("scroll",i,d(!1)),document[l]("keypress",i,d(!1)),document[l]("click",i,d(!1))}}},{}],6:[function(t,e,n){e.exports=function(){return"PerformanceObserver"in window&&"function"==typeof window.PerformanceObserver}},{}],7:[function(t,e,n){function r(t){for(var e=t;e&&!e.hasOwnProperty(u);)e=Object.getPrototypeOf(e);e&&o(e)}function o(t){s.inPlace(t,[u,d],"-",i)}function i(t,e){return t[1]}var a=t("ee").get("events"),s=t("wrap-function")(a,!0),c=t("gos"),f=XMLHttpRequest,u="addEventListener",d="removeEventListener";e.exports=a,"getPrototypeOf"in Object?(r(document),r(window),r(f.prototype)):f.prototype.hasOwnProperty(u)&&(o(window),o(f.prototype)),a.on(u+"-start",function(t,e){var n=t[1];if(null!==n&&("function"==typeof n||"object"==typeof n)){var r=c(n,"nr@wrapped",function(){function t(){if("function"==typeof n.handleEvent)return n.handleEvent.apply(n,arguments)}var e={object:t,"function":n}[typeof n];return e?s(e,"fn-",null,e.name||"anonymous"):n});this.wrapped=t[1]=r}}),a.on(d+"-start",function(t){t[1]=this.wrapped||t[1]})},{}],8:[function(t,e,n){function r(t,e,n){var r=t[e];"function"==typeof r&&(t[e]=function(){var t=i(arguments),e={};o.emit(n+"before-start",[t],e);var a;e[m]&&e[m].dt&&(a=e[m].dt);var s=r.apply(this,t);return o.emit(n+"start",[t,a],s),s.then(function(t){return o.emit(n+"end",[null,t],s),t},function(t){throw o.emit(n+"end",[t],s),t})})}var o=t("ee").get("fetch"),i=t(33),a=t(32);e.exports=o;var s=window,c="fetch-",f=c+"body-",u=["arrayBuffer","blob","json","text","formData"],d=s.Request,p=s.Response,l=s.fetch,h="prototype",m="nr@context";d&&p&&l&&(a(u,function(t,e){r(d[h],e,f),r(p[h],e,f)}),r(s,"fetch",c),o.on(c+"end",function(t,e){var n=this;if(e){var r=e.headers.get("content-length");null!==r&&(n.rxSize=r),o.emit(c+"done",[null,e],n)}else o.emit(c+"done",[t],n)}))},{}],9:[function(t,e,n){var r=t("ee").get("history"),o=t("wrap-function")(r);e.exports=r;var i=window.history&&window.history.constructor&&window.history.constructor.prototype,a=window.history;i&&i.pushState&&i.replaceState&&(a=i),o.inPlace(a,["pushState","replaceState"],"-")},{}],10:[function(t,e,n){function r(t){function e(){f.emit("jsonp-end",[],l),t.removeEventListener("load",e,c(!1)),t.removeEventListener("error",n,c(!1))}function n(){f.emit("jsonp-error",[],l),f.emit("jsonp-end",[],l),t.removeEventListener("load",e,c(!1)),t.removeEventListener("error",n,c(!1))}var r=t&&"string"==typeof t.nodeName&&"script"===t.nodeName.toLowerCase();if(r){var o="function"==typeof t.addEventListener;if(o){var a=i(t.src);if(a){var d=s(a),p="function"==typeof d.parent[d.key];if(p){var l={};u.inPlace(d.parent,[d.key],"cb-",l),t.addEventListener("load",e,c(!1)),t.addEventListener("error",n,c(!1)),f.emit("new-jsonp",[t.src],l)}}}}}function o(){return"addEventListener"in window}function i(t){var e=t.match(d);return e?e[1]:null}function a(t,e){var n=t.match(l),r=n[1],o=n[3];return o?a(o,e[r]):e[r]}function s(t){var e=t.match(p);return e&&e.length>=3?{key:e[2],parent:a(e[1],window)}:{key:t,parent:window}}var c=t(23),f=t("ee").get("jsonp"),u=t("wrap-function")(f);if(e.exports=f,o()){var d=/[?&](?:callback|cb)=([^&#]+)/,p=/(.*)\.([^.]+)/,l=/^(\w+)(\.|$)(.*)$/,h=["appendChild","insertBefore","replaceChild"];Node&&Node.prototype&&Node.prototype.appendChild?u.inPlace(Node.prototype,h,"dom-"):(u.inPlace(HTMLElement.prototype,h,"dom-"),u.inPlace(HTMLHeadElement.prototype,h,"dom-"),u.inPlace(HTMLBodyElement.prototype,h,"dom-")),f.on("dom-start",function(t){r(t[0])})}},{}],11:[function(t,e,n){var r=t("ee").get("mutation"),o=t("wrap-function")(r),i=NREUM.o.MO;e.exports=r,i&&(window.MutationObserver=function(t){return this instanceof i?new i(o(t,"fn-")):i.apply(this,arguments)},MutationObserver.prototype=i.prototype)},{}],12:[function(t,e,n){function r(t){var e=i.context(),n=s(t,"executor-",e,null,!1),r=new f(n);return i.context(r).getCtx=function(){return e},r}var o=t("wrap-function"),i=t("ee").get("promise"),a=t("ee").getOrSetContext,s=o(i),c=t(32),f=NREUM.o.PR;e.exports=i,f&&(window.Promise=r,["all","race"].forEach(function(t){var e=f[t];f[t]=function(n){function r(t){return function(){i.emit("propagate",[null,!o],a,!1,!1),o=o||!t}}var o=!1;c(n,function(e,n){Promise.resolve(n).then(r("all"===t),r(!1))});var a=e.apply(f,arguments),s=f.resolve(a);return s}}),["resolve","reject"].forEach(function(t){var e=f[t];f[t]=function(t){var n=e.apply(f,arguments);return t!==n&&i.emit("propagate",[t,!0],n,!1,!1),n}}),f.prototype["catch"]=function(t){return this.then(null,t)},f.prototype=Object.create(f.prototype,{constructor:{value:r}}),c(Object.getOwnPropertyNames(f),function(t,e){try{r[e]=f[e]}catch(n){}}),o.wrapInPlace(f.prototype,"then",function(t){return function(){var e=this,n=o.argsToArray.apply(this,arguments),r=a(e);r.promise=e,n[0]=s(n[0],"cb-",r,null,!1),n[1]=s(n[1],"cb-",r,null,!1);var c=t.apply(this,n);return r.nextPromise=c,i.emit("propagate",[e,!0],c,!1,!1),c}}),i.on("executor-start",function(t){t[0]=s(t[0],"resolve-",this,null,!1),t[1]=s(t[1],"resolve-",this,null,!1)}),i.on("executor-err",function(t,e,n){t[1](n)}),i.on("cb-end",function(t,e,n){i.emit("propagate",[n,!0],this.nextPromise,!1,!1)}),i.on("propagate",function(t,e,n){this.getCtx&&!e||(this.getCtx=function(){if(t instanceof Promise)var e=i.context(t);return e&&e.getCtx?e.getCtx():this})}),r.toString=function(){return""+f})},{}],13:[function(t,e,n){var r=t("ee").get("raf"),o=t("wrap-function")(r),i="equestAnimationFrame";e.exports=r,o.inPlace(window,["r"+i,"mozR"+i,"webkitR"+i,"msR"+i],"raf-"),r.on("raf-start",function(t){t[0]=o(t[0],"fn-")})},{}],14:[function(t,e,n){function r(t,e,n){t[0]=a(t[0],"fn-",null,n)}function o(t,e,n){this.method=n,this.timerDuration=isNaN(t[1])?0:+t[1],t[0]=a(t[0],"fn-",this,n)}var i=t("ee").get("timer"),a=t("wrap-function")(i),s="setTimeout",c="setInterval",f="clearTimeout",u="-start",d="-";e.exports=i,a.inPlace(window,[s,"setImmediate"],s+d),a.inPlace(window,[c],c+d),a.inPlace(window,[f,"clearImmediate"],f+d),i.on(c+u,r),i.on(s+u,o)},{}],15:[function(t,e,n){function r(t,e){d.inPlace(e,["onreadystatechange"],"fn-",s)}function o(){var t=this,e=u.context(t);t.readyState>3&&!e.resolved&&(e.resolved=!0,u.emit("xhr-resolved",[],t)),d.inPlace(t,y,"fn-",s)}function i(t){x.push(t),m&&(E?E.then(a):w?w(a):(R=-R,O.data=R))}function a(){for(var t=0;t<x.length;t++)r([],x[t]);x.length&&(x=[])}function s(t,e){return e}function c(t,e){for(var n in t)e[n]=t[n];return e}t(7);var f=t("ee"),u=f.get("xhr"),d=t("wrap-function")(u),p=t(23),l=NREUM.o,h=l.XHR,m=l.MO,v=l.PR,w=l.SI,g="readystatechange",y=["onload","onerror","onabort","onloadstart","onloadend","onprogress","ontimeout"],x=[];e.exports=u;var b=window.XMLHttpRequest=function(t){var e=new h(t);try{u.emit("new-xhr",[e],e),e.addEventListener(g,o,p(!1))}catch(n){try{u.emit("internal-error",[n])}catch(r){}}return e};if(c(h,b),b.prototype=h.prototype,d.inPlace(b.prototype,["open","send"],"-xhr-",s),u.on("send-xhr-start",function(t,e){r(t,e),i(e)}),u.on("open-xhr-start",r),m){var E=v&&v.resolve();if(!w&&!v){var R=1,O=document.createTextNode(R);new m(a).observe(O,{characterData:!0})}}else f.on("fn-end",function(t){t[0]&&t[0].type===g||a()})},{}],16:[function(t,e,n){function r(t){if(!s(t))return null;var e=window.NREUM;if(!e.loader_config)return null;var n=(e.loader_config.accountID||"").toString()||null,r=(e.loader_config.agentID||"").toString()||null,f=(e.loader_config.trustKey||"").toString()||null;if(!n||!r)return null;var h=l.generateSpanId(),m=l.generateTraceId(),v=Date.now(),w={spanId:h,traceId:m,timestamp:v};return(t.sameOrigin||c(t)&&p())&&(w.traceContextParentHeader=o(h,m),w.traceContextStateHeader=i(h,v,n,r,f)),(t.sameOrigin&&!u()||!t.sameOrigin&&c(t)&&d())&&(w.newrelicHeader=a(h,m,v,n,r,f)),w}function o(t,e){return"00-"+e+"-"+t+"-01"}function i(t,e,n,r,o){var i=0,a="",s=1,c="",f="";return o+"@nr="+i+"-"+s+"-"+n+"-"+r+"-"+t+"-"+a+"-"+c+"-"+f+"-"+e}function a(t,e,n,r,o,i){var a="btoa"in window&&"function"==typeof window.btoa;if(!a)return null;var s={v:[0,1],d:{ty:"Browser",ac:r,ap:o,id:t,tr:e,ti:n}};return i&&r!==i&&(s.d.tk=i),btoa(JSON.stringify(s))}function s(t){return f()&&c(t)}function c(t){var e=!1,n={};if("init"in NREUM&&"distributed_tracing"in NREUM.init&&(n=NREUM.init.distributed_tracing),t.sameOrigin)e=!0;else if(n.allowed_origins instanceof Array)for(var r=0;r<n.allowed_origins.length;r++){var o=h(n.allowed_origins[r]);if(t.hostname===o.hostname&&t.protocol===o.protocol&&t.port===o.port){e=!0;break}}return e}function f(){return"init"in NREUM&&"distributed_tracing"in NREUM.init&&!!NREUM.init.distributed_tracing.enabled}function u(){return"init"in NREUM&&"distributed_tracing"in NREUM.init&&!!NREUM.init.distributed_tracing.exclude_newrelic_header}function d(){return"init"in NREUM&&"distributed_tracing"in NREUM.init&&NREUM.init.distributed_tracing.cors_use_newrelic_header!==!1}function p(){return"init"in NREUM&&"distributed_tracing"in NREUM.init&&!!NREUM.init.distributed_tracing.cors_use_tracecontext_headers}var l=t(29),h=t(18);e.exports={generateTracePayload:r,shouldGenerateTrace:s}},{}],17:[function(t,e,n){function r(t){var e=this.params,n=this.metrics;if(!this.ended){this.ended=!0;for(var r=0;r<p;r++)t.removeEventListener(d[r],this.listener,!1);e.aborted||(n.duration=a.now()-this.startTime,this.loadCaptureCalled||4!==t.readyState?null==e.status&&(e.status=0):i(this,t),n.cbTime=this.cbTime,s("xhr",[e,n,this.startTime,this.endTime,"xhr"],this))}}function o(t,e){var n=c(e),r=t.params;r.hostname=n.hostname,r.port=n.port,r.protocol=n.protocol,r.host=n.hostname+":"+n.port,r.pathname=n.pathname,t.parsedOrigin=n,t.sameOrigin=n.sameOrigin}function i(t,e){t.params.status=e.status;var n=v(e,t.lastSize);if(n&&(t.metrics.rxSize=n),t.sameOrigin){var r=e.getResponseHeader("X-NewRelic-App-Data");r&&(t.params.cat=r.split(", ").pop())}t.loadCaptureCalled=!0}var a=t("loader");if(a.xhrWrappable&&!a.disabled){var s=t("handle"),c=t(18),f=t(16).generateTracePayload,u=t("ee"),d=["load","error","abort","timeout"],p=d.length,l=t("id"),h=t(24),m=t(22),v=t(19),w=t(23),g=NREUM.o.REQ,y=window.XMLHttpRequest;a.features.xhr=!0,t(15),t(8),u.on("new-xhr",function(t){var e=this;e.totalCbs=0,e.called=0,e.cbTime=0,e.end=r,e.ended=!1,e.xhrGuids={},e.lastSize=null,e.loadCaptureCalled=!1,e.params=this.params||{},e.metrics=this.metrics||{},t.addEventListener("load",function(n){i(e,t)},w(!1)),h&&(h>34||h<10)||t.addEventListener("progress",function(t){e.lastSize=t.loaded},w(!1))}),u.on("open-xhr-start",function(t){this.params={method:t[0]},o(this,t[1]),this.metrics={}}),u.on("open-xhr-end",function(t,e){"loader_config"in NREUM&&"xpid"in NREUM.loader_config&&this.sameOrigin&&e.setRequestHeader("X-NewRelic-ID",NREUM.loader_config.xpid);var n=f(this.parsedOrigin);if(n){var r=!1;n.newrelicHeader&&(e.setRequestHeader("newrelic",n.newrelicHeader),r=!0),n.traceContextParentHeader&&(e.setRequestHeader("traceparent",n.traceContextParentHeader),n.traceContextStateHeader&&e.setRequestHeader("tracestate",n.traceContextStateHeader),r=!0),r&&(this.dt=n)}}),u.on("send-xhr-start",function(t,e){var n=this.metrics,r=t[0],o=this;if(n&&r){var i=m(r);i&&(n.txSize=i)}this.startTime=a.now(),this.listener=function(t){try{"abort"!==t.type||o.loadCaptureCalled||(o.params.aborted=!0),("load"!==t.type||o.called===o.totalCbs&&(o.onloadCalled||"function"!=typeof e.onload))&&o.end(e)}catch(n){try{u.emit("internal-error",[n])}catch(r){}}};for(var s=0;s<p;s++)e.addEventListener(d[s],this.listener,w(!1))}),u.on("xhr-cb-time",function(t,e,n){this.cbTime+=t,e?this.onloadCalled=!0:this.called+=1,this.called!==this.totalCbs||!this.onloadCalled&&"function"==typeof n.onload||this.end(n)}),u.on("xhr-load-added",function(t,e){var n=""+l(t)+!!e;this.xhrGuids&&!this.xhrGuids[n]&&(this.xhrGuids[n]=!0,this.totalCbs+=1)}),u.on("xhr-load-removed",function(t,e){var n=""+l(t)+!!e;this.xhrGuids&&this.xhrGuids[n]&&(delete this.xhrGuids[n],this.totalCbs-=1)}),u.on("xhr-resolved",function(){this.endTime=a.now()}),u.on("addEventListener-end",function(t,e){e instanceof y&&"load"===t[0]&&u.emit("xhr-load-added",[t[1],t[2]],e)}),u.on("removeEventListener-end",function(t,e){e instanceof y&&"load"===t[0]&&u.emit("xhr-load-removed",[t[1],t[2]],e)}),u.on("fn-start",function(t,e,n){e instanceof y&&("onload"===n&&(this.onload=!0),("load"===(t[0]&&t[0].type)||this.onload)&&(this.xhrCbStart=a.now()))}),u.on("fn-end",function(t,e){this.xhrCbStart&&u.emit("xhr-cb-time",[a.now()-this.xhrCbStart,this.onload,e],e)}),u.on("fetch-before-start",function(t){function e(t,e){var n=!1;return e.newrelicHeader&&(t.set("newrelic",e.newrelicHeader),n=!0),e.traceContextParentHeader&&(t.set("traceparent",e.traceContextParentHeader),e.traceContextStateHeader&&t.set("tracestate",e.traceContextStateHeader),n=!0),n}var n,r=t[1]||{};"string"==typeof t[0]?n=t[0]:t[0]&&t[0].url?n=t[0].url:window.URL&&t[0]&&t[0]instanceof URL&&(n=t[0].href),n&&(this.parsedOrigin=c(n),this.sameOrigin=this.parsedOrigin.sameOrigin);var o=f(this.parsedOrigin);if(o&&(o.newrelicHeader||o.traceContextParentHeader))if("string"==typeof t[0]||window.URL&&t[0]&&t[0]instanceof URL){var i={};for(var a in r)i[a]=r[a];i.headers=new Headers(r.headers||{}),e(i.headers,o)&&(this.dt=o),t.length>1?t[1]=i:t.push(i)}else t[0]&&t[0].headers&&e(t[0].headers,o)&&(this.dt=o)}),u.on("fetch-start",function(t,e){this.params={},this.metrics={},this.startTime=a.now(),this.dt=e,t.length>=1&&(this.target=t[0]),t.length>=2&&(this.opts=t[1]);var n,r=this.opts||{},i=this.target;"string"==typeof i?n=i:"object"==typeof i&&i instanceof g?n=i.url:window.URL&&"object"==typeof i&&i instanceof URL&&(n=i.href),o(this,n);var s=(""+(i&&i instanceof g&&i.method||r.method||"GET")).toUpperCase();this.params.method=s,this.txSize=m(r.body)||0}),u.on("fetch-done",function(t,e){this.endTime=a.now(),this.params||(this.params={}),this.params.status=e?e.status:0;var n;"string"==typeof this.rxSize&&this.rxSize.length>0&&(n=+this.rxSize);var r={txSize:this.txSize,rxSize:n,duration:a.now()-this.startTime};s("xhr",[this.params,r,this.startTime,this.endTime,"fetch"],this)})}},{}],18:[function(t,e,n){var r={};e.exports=function(t){if(t in r)return r[t];var e=document.createElement("a"),n=window.location,o={};e.href=t,o.port=e.port;var i=e.href.split("://");!o.port&&i[1]&&(o.port=i[1].split("/")[0].split("@").pop().split(":")[1]),o.port&&"0"!==o.port||(o.port="https"===i[0]?"443":"80"),o.hostname=e.hostname||n.hostname,o.pathname=e.pathname,o.protocol=i[0],"/"!==o.pathname.charAt(0)&&(o.pathname="/"+o.pathname);var a=!e.protocol||":"===e.protocol||e.protocol===n.protocol,s=e.hostname===document.domain&&e.port===n.port;return o.sameOrigin=a&&(!e.hostname||s),"/"===o.pathname&&(r[t]=o),o}},{}],19:[function(t,e,n){function r(t,e){var n=t.responseType;return"json"===n&&null!==e?e:"arraybuffer"===n||"blob"===n||"json"===n?o(t.response):"text"===n||""===n||void 0===n?o(t.responseText):void 0}var o=t(22);e.exports=r},{}],20:[function(t,e,n){function r(){}function o(t,e,n,r){return function(){return u.recordSupportability("API/"+e+"/called"),i(t+e,[f.now()].concat(s(arguments)),n?null:this,r),n?void 0:this}}var i=t("handle"),a=t(32),s=t(33),c=t("ee").get("tracer"),f=t("loader"),u=t(25),d=NREUM;"undefined"==typeof window.newrelic&&(newrelic=d);var p=["setPageViewName","setCustomAttribute","setErrorHandler","finished","addToTrace","inlineHit","addRelease"],l="api-",h=l+"ixn-";a(p,function(t,e){d[e]=o(l,e,!0,"api")}),d.addPageAction=o(l,"addPageAction",!0),d.setCurrentRouteName=o(l,"routeName",!0),e.exports=newrelic,d.interaction=function(){return(new r).get()};var m=r.prototype={createTracer:function(t,e){var n={},r=this,o="function"==typeof e;return i(h+"tracer",[f.now(),t,n],r),function(){if(c.emit((o?"":"no-")+"fn-start",[f.now(),r,o],n),o)try{return e.apply(this,arguments)}catch(t){throw c.emit("fn-err",[arguments,this,t],n),t}finally{c.emit("fn-end",[f.now()],n)}}}};a("actionText,setName,setAttribute,save,ignore,onEnd,getContext,end,get".split(","),function(t,e){m[e]=o(h,e)}),newrelic.noticeError=function(t,e){"string"==typeof t&&(t=new Error(t)),u.recordSupportability("API/noticeError/called"),i("err",[t,f.now(),!1,e])}},{}],21:[function(t,e,n){function r(t){if(NREUM.init){for(var e=NREUM.init,n=t.split("."),r=0;r<n.length-1;r++)if(e=e[n[r]],"object"!=typeof e)return;return e=e[n[n.length-1]]}}e.exports={getConfiguration:r}},{}],22:[function(t,e,n){e.exports=function(t){if("string"==typeof t&&t.length)return t.length;if("object"==typeof t){if("undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer&&t.byteLength)return t.byteLength;if("undefined"!=typeof Blob&&t instanceof Blob&&t.size)return t.size;if(!("undefined"!=typeof FormData&&t instanceof FormData))try{return JSON.stringify(t).length}catch(e){return}}}},{}],23:[function(t,e,n){var r=!1;try{var o=Object.defineProperty({},"passive",{get:function(){r=!0}});window.addEventListener("testPassive",null,o),window.removeEventListener("testPassive",null,o)}catch(i){}e.exports=function(t){return r?{passive:!0,capture:!!t}:!!t}},{}],24:[function(t,e,n){var r=0,o=navigator.userAgent.match(/Firefox[\/\s](\d+\.\d+)/);o&&(r=+o[1]),e.exports=r},{}],25:[function(t,e,n){function r(t,e){var n=[a,t,{name:t},e];return i("storeMetric",n,null,"api"),n}function o(t,e){var n=[s,t,{name:t},e];return i("storeEventMetrics",n,null,"api"),n}var i=t("handle"),a="sm",s="cm";e.exports={constants:{SUPPORTABILITY_METRIC:a,CUSTOM_METRIC:s},recordSupportability:r,recordCustom:o}},{}],26:[function(t,e,n){function r(){return s.exists&&performance.now?Math.round(performance.now()):(i=Math.max((new Date).getTime(),i))-a}function o(){return i}var i=(new Date).getTime(),a=i,s=t(34);e.exports=r,e.exports.offset=a,e.exports.getLastTimestamp=o},{}],27:[function(t,e,n){function r(t){return!(!t||!t.protocol||"file:"===t.protocol)}e.exports=r},{}],28:[function(t,e,n){function r(t,e){var n=t.getEntries();n.forEach(function(t){"first-paint"===t.name?p("timing",["fp",Math.floor(t.startTime)]):"first-contentful-paint"===t.name&&p("timing",["fcp",Math.floor(t.startTime)])})}function o(t,e){var n=t.getEntries();if(n.length>0){var r=n[n.length-1];if(c&&c<r.startTime)return;p("lcp",[r])}}function i(t){t.getEntries().forEach(function(t){t.hadRecentInput||p("cls",[t])})}function a(t){if(t instanceof v&&!g){var e=Math.round(t.timeStamp),n={type:t.type};e<=l.now()?n.fid=l.now()-e:e>l.offset&&e<=Date.now()?(e-=l.offset,n.fid=l.now()-e):e=l.now(),g=!0,p("timing",["fi",e,n])}}function s(t){"hidden"===t&&(c=l.now(),p("pageHide",[c]))}if(!("init"in NREUM&&"page_view_timing"in NREUM.init&&"enabled"in NREUM.init.page_view_timing&&NREUM.init.page_view_timing.enabled===!1)){var c,f,u,d,p=t("handle"),l=t("loader"),h=t(31),m=t(23),v=NREUM.o.EV;if("PerformanceObserver"in window&&"function"==typeof window.PerformanceObserver){f=new PerformanceObserver(r);try{f.observe({entryTypes:["paint"]})}catch(w){}u=new PerformanceObserver(o);try{u.observe({entryTypes:["largest-contentful-paint"]})}catch(w){}d=new PerformanceObserver(i);try{d.observe({type:"layout-shift",buffered:!0})}catch(w){}}if("addEventListener"in document){var g=!1,y=["click","keydown","mousedown","pointerdown","touchstart"];y.forEach(function(t){document.addEventListener(t,a,m(!1))})}h(s)}},{}],29:[function(t,e,n){function r(){function t(){return e?15&e[n++]:16*Math.random()|0}var e=null,n=0,r=window.crypto||window.msCrypto;r&&r.getRandomValues&&(e=r.getRandomValues(new Uint8Array(31)));for(var o,i="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx",a="",s=0;s<i.length;s++)o=i[s],"x"===o?a+=t().toString(16):"y"===o?(o=3&t()|8,a+=o.toString(16)):a+=o;return a}function o(){return a(16)}function i(){return a(32)}function a(t){function e(){return n?15&n[r++]:16*Math.random()|0}var n=null,r=0,o=window.crypto||window.msCrypto;o&&o.getRandomValues&&Uint8Array&&(n=o.getRandomValues(new Uint8Array(31)));for(var i=[],a=0;a<t;a++)i.push(e().toString(16));return i.join("")}e.exports={generateUuid:r,generateSpanId:o,generateTraceId:i}},{}],30:[function(t,e,n){function r(t,e){if(!o)return!1;if(t!==o)return!1;if(!e)return!0;if(!i)return!1;for(var n=i.split("."),r=e.split("."),a=0;a<r.length;a++)if(r[a]!==n[a])return!1;return!0}var o=null,i=null,a=/Version\/(\S+)\s+Safari/;if(navigator.userAgent){var s=navigator.userAgent,c=s.match(a);c&&s.indexOf("Chrome")===-1&&s.indexOf("Chromium")===-1&&(o="Safari",i=c[1])}e.exports={agent:o,version:i,match:r}},{}],31:[function(t,e,n){function r(t){function e(){t(s&&document[s]?document[s]:document[i]?"hidden":"visible")}"addEventListener"in document&&a&&document.addEventListener(a,e,o(!1))}var o=t(23);e.exports=r;var i,a,s;"undefined"!=typeof document.hidden?(i="hidden",a="visibilitychange",s="visibilityState"):"undefined"!=typeof document.msHidden?(i="msHidden",a="msvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(i="webkitHidden",a="webkitvisibilitychange",s="webkitVisibilityState")},{}],32:[function(t,e,n){function r(t,e){var n=[],r="",i=0;for(r in t)o.call(t,r)&&(n[i]=e(r,t[r]),i+=1);return n}var o=Object.prototype.hasOwnProperty;e.exports=r},{}],33:[function(t,e,n){function r(t,e,n){e||(e=0),"undefined"==typeof n&&(n=t?t.length:0);for(var r=-1,o=n-e||0,i=Array(o<0?0:o);++r<o;)i[r]=t[e+r];return i}e.exports=r},{}],34:[function(t,e,n){e.exports={exists:"undefined"!=typeof window.performance&&window.performance.timing&&"undefined"!=typeof window.performance.timing.navigationStart}},{}],ee:[function(t,e,n){function r(){}function o(t){function e(t){return t&&t instanceof r?t:t?f(t,c,a):a()}function n(n,r,o,i,a){if(a!==!1&&(a=!0),!l.aborted||i){t&&a&&t(n,r,o);for(var s=e(o),c=m(n),f=c.length,u=0;u<f;u++)c[u].apply(s,r);var p=d[y[n]];return p&&p.push([x,n,r,s]),s}}function i(t,e){g[t]=m(t).concat(e)}function h(t,e){var n=g[t];if(n)for(var r=0;r<n.length;r++)n[r]===e&&n.splice(r,1)}function m(t){return g[t]||[]}function v(t){return p[t]=p[t]||o(n)}function w(t,e){l.aborted||u(t,function(t,n){e=e||"feature",y[n]=e,e in d||(d[e]=[])})}var g={},y={},x={on:i,addEventListener:i,removeEventListener:h,emit:n,get:v,listeners:m,context:e,buffer:w,abort:s,aborted:!1};return x}function i(t){return f(t,c,a)}function a(){return new r}function s(){(d.api||d.feature)&&(l.aborted=!0,d=l.backlog={})}var c="nr@context",f=t("gos"),u=t(32),d={},p={},l=e.exports=o();e.exports.getOrSetContext=i,l.backlog=d},{}],gos:[function(t,e,n){function r(t,e,n){if(o.call(t,e))return t[e];var r=n();if(Object.defineProperty&&Object.keys)try{return Object.defineProperty(t,e,{value:r,writable:!0,enumerable:!1}),r}catch(i){}return t[e]=r,r}var o=Object.prototype.hasOwnProperty;e.exports=r},{}],handle:[function(t,e,n){function r(t,e,n,r){o.buffer([t],r),o.emit(t,e,n)}var o=t("ee").get("handle");e.exports=r,r.ee=o},{}],id:[function(t,e,n){function r(t){var e=typeof t;return!t||"object"!==e&&"function"!==e?-1:t===window?0:a(t,i,function(){return o++})}var o=1,i="nr@id",a=t("gos");e.exports=r},{}],loader:[function(t,e,n){function r(){if(!P++){var t=T.info=NREUM.info,e=v.getElementsByTagName("script")[0];if(setTimeout(f.abort,3e4),!(t&&t.licenseKey&&t.applicationID&&e))return f.abort();c(R,function(e,n){t[e]||(t[e]=n)});var n=a();s("mark",["onload",n+T.offset],null,"api"),s("timing",["load",n]);var r=v.createElement("script");0===t.agent.indexOf("http://")||0===t.agent.indexOf("https://")?r.src=t.agent:r.src=h+"://"+t.agent,e.parentNode.insertBefore(r,e)}}function o(){"complete"===v.readyState&&i()}function i(){s("mark",["domContent",a()+T.offset],null,"api")}var a=t(26),s=t("handle"),c=t(32),f=t("ee"),u=t(30),d=t(27),p=t(21),l=t(23),h=p.getConfiguration("ssl")===!1?"http":"https",m=window,v=m.document,w="addEventListener",g="attachEvent",y=m.XMLHttpRequest,x=y&&y.prototype,b=!d(m.location);NREUM.o={ST:setTimeout,SI:m.setImmediate,CT:clearTimeout,XHR:y,REQ:m.Request,EV:m.Event,PR:m.Promise,MO:m.MutationObserver};var E=""+location,R={beacon:"bam.nr-data.net",errorBeacon:"bam.nr-data.net",agent:"js-agent.newrelic.com/nr-spa-1212.min.js"},O=y&&x&&x[w]&&!/CriOS/.test(navigator.userAgent),T=e.exports={offset:a.getLastTimestamp(),now:a,origin:E,features:{},xhrWrappable:O,userAgent:u,disabled:b};if(!b){t(20),t(28),v[w]?(v[w]("DOMContentLoaded",i,l(!1)),m[w]("load",r,l(!1))):(v[g]("onreadystatechange",o),m[g]("onload",r)),s("mark",["firstbyte",a.getLastTimestamp()],null,"api");var P=0}},{}],"wrap-function":[function(t,e,n){function r(t,e){function n(e,n,r,c,f){function nrWrapper(){var i,a,u,p;try{a=this,i=d(arguments),u="function"==typeof r?r(i,a):r||{}}catch(l){o([l,"",[i,a,c],u],t)}s(n+"start",[i,a,c],u,f);try{return p=e.apply(a,i)}catch(h){throw s(n+"err",[i,a,h],u,f),h}finally{s(n+"end",[i,a,p],u,f)}}return a(e)?e:(n||(n=""),nrWrapper[p]=e,i(e,nrWrapper,t),nrWrapper)}function r(t,e,r,o,i){r||(r="");var s,c,f,u="-"===r.charAt(0);for(f=0;f<e.length;f++)c=e[f],s=t[c],a(s)||(t[c]=n(s,u?c+r:r,o,c,i))}function s(n,r,i,a){if(!h||e){var s=h;h=!0;try{t.emit(n,r,i,e,a)}catch(c){o([c,n,r,i],t)}h=s}}return t||(t=u),n.inPlace=r,n.flag=p,n}function o(t,e){e||(e=u);try{e.emit("internal-error",t)}catch(n){}}function i(t,e,n){if(Object.defineProperty&&Object.keys)try{var r=Object.keys(t);return r.forEach(function(n){Object.defineProperty(e,n,{get:function(){return t[n]},set:function(e){return t[n]=e,e}})}),e}catch(i){o([i],n)}for(var a in t)l.call(t,a)&&(e[a]=t[a]);return e}function a(t){return!(t&&t instanceof Function&&t.apply&&!t[p])}function s(t,e){var n=e(t);return n[p]=t,i(t,n,u),n}function c(t,e,n){var r=t[e];t[e]=s(r,n)}function f(){for(var t=arguments.length,e=new Array(t),n=0;n<t;++n)e[n]=arguments[n];return e}var u=t("ee"),d=t(33),p="nr@original",l=Object.prototype.hasOwnProperty,h=!1;e.exports=r,e.exports.wrapFunction=s,e.exports.wrapInPlace=c,e.exports.argsToArray=f},{}]},{},["loader",2,17,5,3,4]); ;NREUM.loader_config={accountID:"3768898",trustKey:"3768898",agentID:"1134285132",licenseKey:"NRJS-2bc9f9fb1efc463f27c",applicationID:"1134285132"} ;NREUM.info={beacon:"bam.nr-data.net",errorBeacon:"bam.nr-data.net",licenseKey:"NRJS-2bc9f9fb1efc463f27c",applicationID:"1134285132",sa:1} newrelic.addRelease("", "Remove-ControllerConfig-r-production-4dd74f6-17d951-17d94f"); </script><meta name=viewport content="width=device-width,initial-scale=1"><meta name=author content="Crossplane Community"><meta name=color-scheme content="light dark"><meta name=docsearch:language content="en"><meta name=generator content="Hugo 0.119.0"><link rel=preload href=/fonts/Avenir-Roman.woff2 as=font type=font/woff2 crossorigin><meta property="og:image" content="/img/crossplane-logo-og.webp"><meta property="twitter:card" content="/img/crossplane-logo-og.webp"><meta property="og:image:width" content="600"><meta property="og:image:height" content="199"><meta property="og:image:alt" content="Crossplane name and popsicle logo"><meta property="twitter:image:alt" content="Crossplane name and popsicle logo"><meta property="og:type" content="website"><meta name=twitter:site content="@crossplane_io"><meta property="og:site_name" content="Crossplane Documentation"><meta name=description content="Compositions are a template for creating Crossplane resources"><meta property="og:url" content="https://docs.crossplane.io/v1.18/concepts/compositions/"><meta name=docsearch:modified content="November 5, 2024"><meta name=docsearch:version content="1.18"><title>Compositions · Crossplane v1.18</title><link rel=canonical href=https://docs.crossplane.io/latest/concepts/compositions/><script>(()=>{var e=window.matchMedia("(prefers-color-scheme: dark)").matches,t=localStorage.getItem("darkSwitch")!==null&&localStorage.getItem("darkSwitch")==="dark",n=localStorage.getItem("darkSwitch")!==null&&localStorage.getItem("darkSwitch")==="light";n&&(e=!1),t||e?document.documentElement.setAttribute("color-theme","dark"):document.documentElement.setAttribute("color-theme","light")})()</script><link rel=stylesheet href=https://cdn.jsdelivr.net/npm/@docsearch/css@3 media=print onload='this.media="all"'><link rel=preconnect href=https://9UXKYX61NK-dsn.algolia.net crossorigin data-proofer-ignore><link href="https://docs.crossplane.io/scss/docs.0346bfd4a8aeace526724de64ddada78a0e5122b3b0c83b1021770d6ddef1160.css" rel=stylesheet><link rel=apple-touch-icon sizes=180x180 href=/apple-touch-icon.png><link rel=icon type=image/png sizes=32x32 href=/favicon-32x32.png><link rel=icon type=image/png sizes=192x192 href=/android-chrome-192x192.png><link rel=icon type=image/png sizes=16x16 href=/favicon-16x16.png><link rel=manifest href=/site.webmanifest><link rel=mask-icon href=/safari-pinned-tab.svg color=#f87c44><meta name=apple-mobile-web-app-title content="Crossplane Docs"><meta name=application-name content="Crossplane Docs"><meta name=msapplication-TileColor content="#333f5b"><meta name=theme-color content="#ffffff"><meta property="og:title" content="Crossplane Docs · v1.18 · Compositions"><meta property="og:description" content="Compositions are a template for creating multiple managed resources as a single object. A Composition composes individual managed resources together into a larger, reusable, solution. An example …"></head><body><svg xmlns="http://www.w3.org/2000/svg" style="display:none"><symbol id="check2" viewBox="0 0 16 16"><path d="M13.854 3.646a.5.5.0 010 .708l-7 7a.5.5.0 01-.708.0l-3.5-3.5a.5.5.0 11.708-.708L6.5 10.293l6.646-6.647a.5.5.0 01.708.0z"/></symbol><symbol id="x" viewBox="0 0 16 16"><path d="M2.146 2.854a.5.5.0 11.708-.708L8 7.293l5.146-5.147a.5.5.0 01.708.708L8.707 8l5.147 5.146a.5.5.0 01-.708.708L8 8.707l-5.146 5.147a.5.5.0 01-.708-.708L7.293 8 2.146 2.854z"/></symbol><symbol id="chevron-expand" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M3.646 9.146a.5.5.0 01.708.0L8 12.793l3.646-3.647a.5.5.0 01.708.708l-4 4a.5.5.0 01-.708.0l-4-4a.5.5.0 010-.708zm0-2.292a.5.5.0 00.708.0L8 3.207l3.646 3.647a.5.5.0 00.708-.708l-4-4a.5.5.0 00-.708.0l-4 4a.5.5.0 000 .708z"/></symbol><symbol id="clipboard" viewBox="0 0 16 16"><path d="M4 1.5H3a2 2 0 00-2 2V14a2 2 0 002 2h10a2 2 0 002-2V3.5a2 2 0 00-2-2h-1v1h1a1 1 0 011 1V14a1 1 0 01-1 1H3a1 1 0 01-1-1V3.5a1 1 0 011-1h1v-1z"/><path d="M9.5 1a.5.5.0 01.5.5v1a.5.5.0 01-.5.5h-3A.5.5.0 016 2.5v-1a.5.5.0 01.5-.5h3zm-3-1A1.5 1.5.0 005 1.5v1A1.5 1.5.0 006.5 4h3A1.5 1.5.0 0011 2.5v-1A1.5 1.5.0 009.5.0h-3z"/></symbol><symbol id="plus" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 2a.5.5.0 01.5.5v5h5a.5.5.0 010 1h-5v5a.5.5.0 01-1 0v-5h-5a.5.5.0 010-1h5v-5A.5.5.0 018 2z"/></symbol><symbol id="three-dots" viewBox="0 0 16 16"><path d="M3 9.5a1.5 1.5.0 110-3 1.5 1.5.0 010 3zm5 0a1.5 1.5.0 110-3 1.5 1.5.0 010 3zm5 0a1.5 1.5.0 110-3 1.5 1.5.0 010 3z"/></symbol><symbol id="info" viewBox="0 0 16 16"><path d="M8 15A7 7 0 118 1a7 7 0 010 14zm0 1A8 8 0 108 0a8 8 0 000 16z"/><path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545.0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275.0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 11-2 0 1 1 0 012 0z"/></symbol><symbol id="check" viewBox="0 0 16 16"><path d="M8 15A7 7 0 118 1a7 7 0 010 14zm0 1A8 8 0 108 0a8 8 0 000 16z"/><path d="M10.97 4.97a.235.235.0 00-.02.022L7.477 9.417 5.384 7.323a.75.75.0 00-1.06 1.06L6.97 11.03a.75.75.0 001.079-.02l3.992-4.99A.75.75.0 0010.97 4.97z"/></symbol><symbol id="exclamation" viewBox="0 0 16 16"><path d="M8 15A7 7 0 118 1a7 7 0 010 14zm0 1A8 8 0 108 0a8 8 0 000 16z"/><path d="M7.002 11a1 1 0 112 0 1 1 0 01-2 0zM7.1 4.995a.905.905.0 111.8.0l-.35 3.507a.552.552.0 01-1.1.0L7.1 4.995z"/></symbol><symbol id="x-circle" viewBox="0 0 16 16"><path d="M8 15A7 7 0 118 1a7 7 0 010 14zm0 1A8 8 0 108 0a8 8 0 000 16z"/><path d="M4.646 4.646a.5.5.0 01.708.0L8 7.293l2.646-2.647a.5.5.0 01.708.708L8.707 8l2.647 2.646a.5.5.0 01-.708.708L8 8.707l-2.646 2.647a.5.5.0 01-.708-.708L7.293 8 4.646 5.354a.5.5.0 010-.708z"/></symbol><symbol id="fire" viewBox="0 0 16 16"><path d="M8 16c3.314.0 6-2 6-5.5.0-1.5-.5-4-2.5-6 .25 1.5-1.25 2-1.25 2C11 4 9 .5 6 0c.357 2 .5 4-2 6-1.25 1-2 2.729-2 4.5C2 14 4.686 16 8 16zm0-1c-1.657.0-3-1-3-2.75.0-.75.25-2 1.25-3C6.125 10 7 10.5 7 10.5c-.375-1.25.5-3.25 2-3.5-.179 1-.25 2 1 3 .625.5 1 1.364 1 2.25C11 14 9.657 15 8 15z"/></symbol><symbol id="search" viewBox="0 0 16 16"><path d="M11.742 10.344a6.5 6.5.0 10-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 001.415-1.414l-3.85-3.85a1.007 1.007.0 00-.115-.1zM12 6.5a5.5 5.5.0 11-11 0 5.5 5.5.0 0111 0z"/></symbol><symbol id="clipboard-check" viewBox="0 0 16 16"><path d="M6.5.0A1.5 1.5.0 005 1.5v1A1.5 1.5.0 006.5 4h3A1.5 1.5.0 0011 2.5v-1A1.5 1.5.0 009.5.0h-3zm3 1a.5.5.0 01.5.5v1a.5.5.0 01-.5.5h-3A.5.5.0 016 2.5v-1a.5.5.0 01.5-.5h3z"/><path d="M4 1.5H3a2 2 0 00-2 2V14a2 2 0 002 2h10a2 2 0 002-2V3.5a2 2 0 00-2-2h-1v1A2.5 2.5.0 019.5 5h-3A2.5 2.5.0 014 2.5v-1zm6.854 7.354-3 3a.5.5.0 01-.708.0l-1.5-1.5a.5.5.0 01.708-.708L7.5 10.793l2.646-2.647a.5.5.0 01.708.708z"/></symbol><symbol id="pencil-square" viewBox="0 0 16 16"><path d="M15.502 1.94a.5.5.0 010 .706L14.459 3.69l-2-2L13.502.646a.5.5.0 01.707.0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5.0 00-.121.196l-.805 2.414a.25.25.0 00.316.316l2.414-.805a.5.5.0 00.196-.12l6.813-6.814z"/><path fill-rule="evenodd" d="M1 13.5A1.5 1.5.0 002.5 15h11a1.5 1.5.0 001.5-1.5v-6a.5.5.0 00-1 0v6a.5.5.0 01-.5.5h-11a.5.5.0 01-.5-.5v-11a.5.5.0 01.5-.5H9a.5.5.0 000-1H2.5A1.5 1.5.0 001 2.5v11z"/></symbol><symbol id="github" viewBox="0 0 16 16"><path d="M8 0C3.58.0.0 3.58.0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38.0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95.0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12.0.0.67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15.0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48.0 1.07-.01 1.93-.01 2.2.0.21.15.46.55.38A8.012 8.012.0 0016 8c0-4.42-3.58-8-8-8z"/></symbol><symbol id="box-arrow-up-right" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.636 3.5a.5.5.0 00-.5-.5H1.5A1.5 1.5.0 000 4.5v10A1.5 1.5.0 001.5 16h10a1.5 1.5.0 001.5-1.5V7.864a.5.5.0 00-1 0V14.5a.5.5.0 01-.5.5h-10a.5.5.0 01-.5-.5v-10a.5.5.0 01.5-.5h6.636a.5.5.0 00.5-.5z"/><path fill-rule="evenodd" d="M16 .5a.5.5.0 00-.5-.5h-5a.5.5.0 000 1h3.793L6.146 9.146a.5.5.0 10.708.708L15 1.707V5.5a.5.5.0 001 0v-5z"/></symbol></svg><header class="navbar docs-navbar navbar-expand-lg py-0 align-items-center"><div class=docs-left-toggle><button class=navbar-toggler type=button data-bs-toggle=offcanvas data-bs-target=#bdSidebar aria-controls=bdSidebar aria-label="Toggle docs content"><svg xmlns="http://www.w3.org/2000/svg" width="1.5rem" height="1.5rem" fill="currentcolor" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M2.5 11.5A.5.5.0 013 11h10a.5.5.0 010 1H3a.5.5.0 01-.5-.5zm0-4A.5.5.0 013 7h10a.5.5.0 010 1H3a.5.5.0 01-.5-.5zm0-4A.5.5.0 013 3h10a.5.5.0 010 1H3a.5.5.0 01-.5-.5z"/></svg> <span class="d-none fs-6 pe-1">Browse</span></button></div><div class="docs-right-toggle order-3"><button class=navbar-toggler type=button data-bs-toggle=offcanvas data-bs-target=#offcanvas aria-controls=offcanvas aria-label="Toggle Crossplane navigation"><svg class="bi white" aria-hidden="true"><use xlink:href="#three-dots"/></svg></button></div><div class=navbar-brand><a href=https://www.crossplane.io aria-label=Crossplane><img src=/img/crossplane-logo.svg alt="Crossplane logo" srcset="/img/crossplane-logo.svg 1x, /img/crossplane-logo.svg 2x" width=152px decoding=async data-nimg=future loading=lazy></a></div><div class="w-100 offcanvas-lg offcanvas-end" tabindex=-1 id=offcanvas aria-labelledby=offcanvasLabel><div class="offcanvas-body p-0"><div class="offcanvas-header p-0"><div class=navbar-brand><a href=https://www.crossplane.io aria-label=Crossplane><img src=/img/crossplane-logo.svg alt="Crossplane logo" srcset="/img/crossplane-logo.svg 1x, /img/crossplane-logo.svg 2x" width=152px decoding=async data-nimg=future loading=lazy></a></div><button type=button class="btn-close btn-close-white" data-bs-dismiss=offcanvas aria-label=Close data-bs-target=#offcanvas></button></div><div class="navbar-center-links collapse navbar-collapse justify-content-evenly show"><ul class="navbar-nav align-items-center"><li class=nav-item><a class=navbar-link href=https://www.crossplane.io/why-control-planes>Why Control Planes?</a></li><li class=nav-item><a class=navbar-link aria-current=page href=https://docs.crossplane.io/>Documentation</a></li><li class=nav-item><a class=navbar-link href=https://www.crossplane.io/community>Community</a></li><li class=nav-item><a class=navbar-link href=https://blog.crossplane.io/>Blog</a></li></ul></div><div class="navbar-icons flex-shrink-1 show"><ul class=navbar-nav><li class="nav-item col-xs p-2"><a class=navbar-link href=https://github.com/crossplane title="Crossplane Github Repository" target=_blank rel=noopener><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentcolor" class="icon-github" viewBox="0 0 16 16"><path d="M8 0C3.58.0.0 3.58.0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38.0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95.0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12.0.0.67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15.0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48.0 1.07-.01 1.93-.01 2.2.0.21.15.46.55.38A8.012 8.012.0 0016 8c0-4.42-3.58-8-8-8z"/></svg><span class=icon-label>Crossplane GitHub</span></a></li><li class="nav-item col-xs p-2"><div id=slack><a class=navbar-link href=https://slack.crossplane.io title="Join the Crossplane Slack" target=_blank rel=noopener><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentcolor" class="icon-slack" viewBox="0 0 16 16"><path d="M3.362 10.11c0 .926-.756 1.681-1.681 1.681S0 11.036.0 10.111C0 9.186.756 8.43 1.68 8.43h1.682v1.68zm.846.0c0-.924.756-1.68 1.681-1.68s1.681.756 1.681 1.68v4.21c0 .924-.756 1.68-1.68 1.68a1.685 1.685.0 01-1.682-1.68v-4.21zM5.89 3.362c-.926.0-1.682-.756-1.682-1.681S4.964.0 5.89.0s1.68.756 1.68 1.68v1.682H5.89zm0 .846c.924.0 1.68.756 1.68 1.681S6.814 7.57 5.89 7.57H1.68C.757 7.57.0 6.814.0 5.89c0-.926.756-1.682 1.68-1.682h4.21zm6.749 1.682c0-.926.755-1.682 1.68-1.682.925.0 1.681.756 1.681 1.681s-.756 1.681-1.68 1.681h-1.681V5.89zm-.848.0c0 .924-.755 1.68-1.68 1.68A1.685 1.685.0 018.43 5.89V1.68C8.43.757 9.186.0 10.11.0c.926.0 1.681.756 1.681 1.68v4.21zm-1.681 6.748c.926.0 1.682.756 1.682 1.681S11.036 16 10.11 16s-1.681-.756-1.681-1.68v-1.682h1.68zm0-.847c-.924.0-1.68-.755-1.68-1.68.0-.925.756-1.681 1.68-1.681h4.21c.924.0 1.68.756 1.68 1.68.0.926-.756 1.681-1.68 1.681h-4.21z"/></svg><span class=icon-label>Crossplane Slack</span></a></div></li><li class="nav-item col-x p-2"><div class="vr d-lg-flex mx-lg-2 text-white"></div></li><li class="nav-item col-xs p-2"><div class="form-check form-switch color-switcher"><input class="d-flex form-check-input" type=checkbox id=darkSwitch> <label class="d-flex navbar-link form-check-label" for=darkSwitch>Dark Mode</label></div></li></ul></div></div></div></header><div class="bd-layout docs-container" data-bs-spy=scroll data-bs-target=#TableOfContents data-bs-threshold=0,1 data-bs-root-margin="0% 0% -75%"><aside class=bd-sidebar><div class="offcanvas-lg offcanvas-start bd-sidebar-container" tabindex=-1 id=bdSidebar aria-labelledby=bdSidebarOffcanvasLabel><div class="offcanvas-header pb-4 border-bottom"><div class="d-flex offcanvas-title fw-bold" id=bdNavbarOffcanvasLabel>Crossplane Documentation - v1.18</div><div class=d-flex><button type=button class="btn-close bi align-self-center p-0" data-bs-dismiss=offcanvas aria-label=Close data-bs-target=#bdSidebar></button></div></div><div class=offcanvas-body><div class="container-fluid p-0"><div class="search-container d-flex row pt-3 ps-4 docsearch opacity-50" data-bs-target=#bdSidebar data-bs-dismiss=offcanvas aria-label="Docs navigation"><div class=p-0 id=docSearch></div></div><nav class="bd-links-nav w-100" aria-label="Docs navigation"><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.18/>Overview</a></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.18/getting-started/>Getting Started</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" aria-label="Close or Expand Getting Started Section"> <label for=collapse-83678735 class="sidebar-label collapsed" data-bs-toggle=collapse data-bs-target=#collapse-83678735 aria-expanded=false aria-label="Close or Expand Getting Started Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div><div class="container flex-row collapse" id=collapse-83678735><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/getting-started/introduction/>Crossplane Introduction</a></div></div><div class="container flex-row collapse" id=collapse-83678735><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/getting-started/provider-aws/>AWS Quickstart</a></div></div><div class="container flex-row collapse" id=collapse-83678735><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/getting-started/provider-azure/>Azure Quickstart</a></div></div><div class="container flex-row collapse" id=collapse-83678735><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/getting-started/provider-gcp/>GCP Quickstart</a></div></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.18/software/>Install, Upgrade and Uninstall</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" aria-label="Close or Expand Install, Upgrade and Uninstall Section"> <label for=collapse-2ea344ac class="sidebar-label collapsed" data-bs-toggle=collapse data-bs-target=#collapse-2ea344ac aria-expanded=false aria-label="Close or Expand Install, Upgrade and Uninstall Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div><div class="container flex-row collapse" id=collapse-2ea344ac><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/software/install/>Install Crossplane</a></div></div><div class="container flex-row collapse" id=collapse-2ea344ac><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/software/upgrade/>Upgrade Crossplane</a></div></div><div class="container flex-row collapse" id=collapse-2ea344ac><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/software/uninstall/>Uninstall Crossplane</a></div></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100 active-parent"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.18/concepts/>Concepts</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" checked aria-label="Close or Expand Concepts Section"> <label for=collapse-4c9a67bb class=sidebar-label data-bs-toggle=collapse data-bs-target=#collapse-4c9a67bb aria-expanded=false aria-label="Close or Expand Concepts Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/concepts/pods/>Crossplane Pods</a></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/concepts/providers/>Providers</a></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/concepts/managed-resources/>Managed Resources</a></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex active" href=https://docs.crossplane.io/v1.18/concepts/compositions/>Compositions</a></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/concepts/composition-revisions/>Composition Revisions</a></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/concepts/composite-resource-definitions/>Composite Resource Definitions</a></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/concepts/composite-resources/>Composite Resources</a></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/concepts/claims/>Claims</a></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/concepts/environment-configs/>Environment Configurations</a></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/concepts/usages/>Usages</a></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/concepts/connection-details/>Connection Details</a></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/concepts/packages/>Configuration Packages</a></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/concepts/server-side-apply/>Server-Side Apply</a></div></div><div class="container flex-row collapse show" id=collapse-4c9a67bb><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/concepts/image-configs/>Image Configs</a></div></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.18/guides/>Guides</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" aria-label="Close or Expand Guides Section"> <label for=collapse-0092279e class="sidebar-label collapsed" data-bs-toggle=collapse data-bs-target=#collapse-0092279e aria-expanded=false aria-label="Close or Expand Guides Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div><div class="container flex-row collapse" id=collapse-0092279e><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/guides/disaster-recovery/>Disaster Recovery with Crossplane</a></div></div><div class="container flex-row collapse" id=collapse-0092279e><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/guides/metrics/>Metrics</a></div></div><div class="container flex-row collapse" id=collapse-0092279e><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/guides/function-patch-and-transform/>Function Patch and Transform</a></div></div><div class="container flex-row collapse" id=collapse-0092279e><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/guides/write-a-composition-function-in-go/>Write a Composition Function in Go</a></div></div><div class="container flex-row collapse" id=collapse-0092279e><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/guides/write-a-composition-function-in-python/>Write a Composition Function in Python</a></div></div><div class="container flex-row collapse" id=collapse-0092279e><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/guides/import-existing-resources/>Import Existing Resources</a></div></div><div class="container flex-row collapse" id=collapse-0092279e><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/guides/vault-as-secret-store/>Vault as an External Secret Store</a></div></div><div class="container flex-row collapse" id=collapse-0092279e><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/guides/vault-injection/>Vault Credential Injection</a></div></div><div class="container flex-row collapse" id=collapse-0092279e><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/guides/multi-tenant/>Multi-Tenant Crossplane</a></div></div><div class="container flex-row collapse" id=collapse-0092279e><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/guides/crossplane-with-argo-cd/>Configuring Crossplane with Argo CD</a></div></div><div class="container flex-row collapse" id=collapse-0092279e><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/guides/self-signed-ca-certs/>Self-Signed CA Certs</a></div></div><div class="container flex-row collapse" id=collapse-0092279e><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/guides/troubleshoot-crossplane/>Troubleshoot Crossplane</a></div></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.18/cli/>CLI Reference</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" aria-label="Close or Expand CLI Reference Section"> <label for=collapse-ffd26267 class="sidebar-label collapsed" data-bs-toggle=collapse data-bs-target=#collapse-ffd26267 aria-expanded=false aria-label="Close or Expand CLI Reference Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div><div class="container flex-row collapse" id=collapse-ffd26267><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/cli/command-reference/>Command Reference</a></div></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.18/api/>API Reference</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" aria-label="Close or Expand API Reference Section"> <label for=collapse-6144acbe class="sidebar-label collapsed" data-bs-toggle=collapse data-bs-target=#collapse-6144acbe aria-expanded=false aria-label="Close or Expand API Reference Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.18/learn/>Learn More</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" aria-label="Close or Expand Learn More Section"> <label for=collapse-a721e305 class="sidebar-label collapsed" data-bs-toggle=collapse data-bs-target=#collapse-a721e305 aria-expanded=false aria-label="Close or Expand Learn More Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div><div class="container flex-row collapse" id=collapse-a721e305><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/learn/release-cycle/>Release Cycle</a></div></div><div class="container flex-row collapse" id=collapse-a721e305><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.18/learn/feature-lifecycle/>Feature Lifecycle</a></div></div></div><div class="section-container container pe-0 pt-1"><div class=nav-container><a href=https://docs.crossplane.io/contribute/ class="d-inline-flex align-items-center">Contributing Guide</a></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href="https://github.com/orgs/crossplane/projects/20/views/9?pane=info" target=_blank>Crossplane Roadmap</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><a href="https://github.com/orgs/crossplane/projects/20/views/9?pane=info"><svg class="flex bi"><use xlink:href="#box-arrow-up-right"/></svg></a></div></div></div></nav></div></div></aside><main class="bd-main order-1"><div class="bd-intro pt-2 ps-lg-2"><div class="d-md-flex flex-md-row-reverse align-items-center justify-content-between"><div class="mb-3 mb-md-0 d-flex"><div class="dropdown float-end bd-dropdown"><a class="btn btn-outline-secondary dropdown-toggle bd-dropdown-item text-reset" href=# role=button id=dropdownMenuLink data-bs-toggle=dropdown aria-haspopup=true aria-expanded=false>v1.18<div class="badge rounded-pill latest">Latest</div></a><div class="dropdown-menu bd-border-color bd-dropdown" aria-labelledby=dropdownMenuLink><a class="dropdown-item bd-dropdown-item" href=https://docs.crossplane.io/master/concepts/compositions/>master</a> <a class="dropdown-item bd-dropdown-item active" aria-current=true href=https://docs.crossplane.io/v1.18/concepts/compositions/>v1.18<div class="badge rounded-pill latest">Latest</div></a><a class="dropdown-item bd-dropdown-item" href=https://docs.crossplane.io/v1.17/concepts/compositions/>v1.17</a> <a class="dropdown-item bd-dropdown-item" href=https://docs.crossplane.io/v1.16/concepts/compositions/>v1.16</a></div></div></div><h1 class="bd-title mb-0" id=content>Compositions</h1></div></div><div class="bd-toc mt-3 mb-5 my-lg-0 ps-xl-3 mb-lg-5"><button class="btn btn-link p-md-0 mb-2 mb-md-0 text-decoration-none bd-toc-toggle d-md-none" type=button data-bs-toggle=collapse data-bs-target=#tocContents aria-expanded=false aria-controls=tocContents> On this page<svg class="bi d-md-none ms-2" aria-hidden="true"><use xlink:href="#chevron-expand"/></svg></button> <strong class="d-none d-md-block h6 my-2">On this page</strong><hr class="d-none d-md-block my-2"><div class="collapse bd-toc-collapse" id=tocContents><nav id=TableOfContents><ul class=nav><li class=nav-item><a class=nav-link href=#create-a-composition>Create a Composition</a><ul class=nav><li class=nav-item><a class=nav-link href=#install-a-composition-function>Install a composition function</a></li><li class=nav-item><a class=nav-link href=#verify-a-composition-function>Verify a composition function</a></li><li class=nav-item><a class=nav-link href=#use-a-function-in-a-composition>Use a function in a composition</a></li><li class=nav-item><a class=nav-link href=#use-a-pipeline-of-functions-in-a-composition>Use a pipeline of functions in a composition</a></li><li class=nav-item><a class=nav-link href=#enable-composite-resources>Enable composite resources</a></li><li class=nav-item><a class=nav-link href=#store-connection-details>Store connection details</a><ul class=nav><li class=nav-item><a class=nav-link href=#composite-resource-combined-secret>Composite resource combined secret</a></li><li class=nav-item><a class=nav-link href=#composed-resource-secrets>Composed resource secrets</a></li><li class=nav-item><a class=nav-link href=#external-secret-stores>External secret stores</a></li></ul></li></ul></li><li class=nav-item><a class=nav-link href=#test-a-composition>Test a composition</a></li><li class=nav-item><a class=nav-link href=#verify-a-composition>Verify a Composition</a></li><li class=nav-item><a class=nav-link href=#composition-validation>Composition validation</a><ul class=nav><li class=nav-item><a class=nav-link href=#composition-schema-aware-validation>Composition schema aware validation</a><ul class=nav><li class=nav-item><a class=nav-link href=#schema-aware-validation-modes>Schema aware validation modes</a></li></ul></li></ul></li><li class=nav-item><a class=nav-link href=#write-a-composition-function>Write a composition function</a></li><li class=nav-item><a class=nav-link href=#how-composition-functions-work>How composition functions work</a><ul class=nav><li class=nav-item><a class=nav-link href=#observed-state>Observed state</a></li><li class=nav-item><a class=nav-link href=#desired-state>Desired state</a></li><li class=nav-item><a class=nav-link href=#function-input>Function input</a></li><li class=nav-item><a class=nav-link href=#function-pipeline-context>Function pipeline context</a></li></ul></li></ul></li></ul></nav><nav class=pt-3><div class=pb-2><svg class="bi" width="1em" height="1em"><use xlink:href="#pencil-square"/></svg><span class=ps-1><a target=_blank href="https://github.com/crossplane/docs/issues/new?title=[Web%20Bug]%20-%20Compositions&amp;body=%3c!--%20What%27s%20the%20problem?%20--%3e%0a%0a%0aURL:%20https://docs.crossplane.io/v1.18/concepts/compositions/">Report a problem</a></span></div><div><svg class="bi" width="1em" height="1em"><use xlink:href="#github"/></svg><span class=ps-1><a href=https://github.com/crossplane/docs/tree/master/content/v1.18/concepts/compositions.md>View page source</a></span></div></div></nav></div><div class="bd-content ps-lg-2 DocSearch-content"><p>Compositions are a template for creating multiple managed resources as a single object.</p><p>A Composition <em>composes</em> individual managed resources together into a larger, reusable, solution.</p><p>An example Composition may combine a virtual machine, storage resources and networking policies. A Composition template links all these individual resources together.</p><p>Here&rsquo;s an example Composition. When you create an <code><highlight-term id=1731573034653319656 data-label=intro data-line=8>AcmeBucket</highlight-term></code> composite resource (XR) that uses this Composition, Crossplane uses the template to create the Amazon S3 <code><highlight-term id=1731573034653357765 data-label=intro data-line=18>Bucket</highlight-term></code> managed resource.</p><div class=highlight label=intro><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-0-1><a class=lnlinks href=#hl-0-1> 1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>apiextensions.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-2><a class=lnlinks href=#hl-0-2> 2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Composition</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-3><a class=lnlinks href=#hl-0-3> 3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-4><a class=lnlinks href=#hl-0-4> 4</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>example</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-5><a class=lnlinks href=#hl-0-5> 5</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-6><a class=lnlinks href=#hl-0-6> 6</a></span><span class=cl><span class=w> </span><span class=nt>compositeTypeRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-7><a class=lnlinks href=#hl-0-7> 7</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>custom-api.example.org/v1alpha1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-8><a class=lnlinks href=#hl-0-8> 8</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>AcmeBucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-9><a class=lnlinks href=#hl-0-9> 9</a></span><span class=cl><span class=w> </span><span class=nt>mode</span><span class=p>:</span><span class=w> </span><span class=l>Pipeline</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-10><a class=lnlinks href=#hl-0-10>10</a></span><span class=cl><span class=w> </span><span class=nt>pipeline</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-11><a class=lnlinks href=#hl-0-11>11</a></span><span class=cl><span class=w> </span>- <span class=nt>step</span><span class=p>:</span><span class=w> </span><span class=l>patch-and-transform</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-12><a class=lnlinks href=#hl-0-12>12</a></span><span class=cl><span class=w> </span><span class=nt>functionRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-13><a class=lnlinks href=#hl-0-13>13</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>function-patch-and-transform</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-14><a class=lnlinks href=#hl-0-14>14</a></span><span class=cl><span class=w> </span><span class=nt>input</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-15><a class=lnlinks href=#hl-0-15>15</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>pt.fn.crossplane.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-16><a class=lnlinks href=#hl-0-16>16</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Resources</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-17><a class=lnlinks href=#hl-0-17>17</a></span><span class=cl><span class=w> </span><span class=nt>resources</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-18><a class=lnlinks href=#hl-0-18>18</a></span><span class=cl><span class=w> </span>- <span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>storage-bucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-19><a class=lnlinks href=#hl-0-19>19</a></span><span class=cl><span class=w> </span><span class=nt>base</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-20><a class=lnlinks href=#hl-0-20>20</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>s3.aws.upbound.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-21><a class=lnlinks href=#hl-0-21>21</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Bucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-22><a class=lnlinks href=#hl-0-22>22</a></span><span class=cl><span class=w> </span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-23><a class=lnlinks href=#hl-0-23>23</a></span><span class=cl><span class=w> </span><span class=nt>forProvider</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-24><a class=lnlinks href=#hl-0-24>24</a></span><span class=cl><span class=w> </span><span class=nt>region</span><span class=p>:</span><span class=w> </span><span class=s2>&#34;us-east-2&#34;</span><span class=w> </span></span></span></code></pre></div><div class="accordion mb-3" id=confused-about-compositions-xrds-xrs-and-claims-1591-Parent><div class=accordion-item><h2 class=accordion-header id=confused-about-compositions-xrds-xrs-and-claims-1591><button class="accordion-button collapsed" type=button data-bs-toggle=collapse data-bs-target=#confused-about-compositions-xrds-xrs-and-claims-1591-Content aria-expanded=false aria-controls=confused-about-compositions-xrds-xrs-and-claims-1591-Content> Confused about Compositions, XRDs, XRs and Claims?</button></h2><div id=confused-about-compositions-xrds-xrs-and-claims-1591-Content class="accordion-collapse collapse" aria-labelledby=confused-about-compositions-xrds-xrs-and-claims-1591 data-bs-parent=#confused-about-compositions-xrds-xrs-and-claims-1591-Parent><div class="accordion-body rounded-bottom"><p>Crossplane has four core components that users commonly mix up:</p><ul><li>Compositions - This page. A template to define how to create resources.</li><li><a href=https://docs.crossplane.io/v1.18/concepts/composite-resource-definitions/>Composite Resource Definition</a> (<code>XRD</code>) - A custom API specification.</li><li><a href=https://docs.crossplane.io/v1.18/concepts/composite-resources/>Composite Resource</a> (<code>XR</code>) - Created by using the custom API defined in a Composite Resource Definition. XRs use the Composition template to create new managed resources.</li><li><a href=https://docs.crossplane.io/v1.18/concepts/claims/>Claims</a> (<code>XRC</code>) - Like a Composite Resource, but with namespace scoping.</li></ul></div></div></div></div><h2 id=create-a-composition>Create a Composition <a class=anchor-link id=create-a-composition href=#create-a-composition aria-label="Link to this section: Create a Composition"></a></h2><p>Creating a Composition consists of:</p><ul><li><a href=#use-a-function-in-a-composition>Using composition functions</a> to define the resources to create.</li><li><a href=#enable-composite-resources>Enabling composite resources</a> to use the Composition template.</li></ul><p>A Composition is a pipeline of composition functions.</p><p>Composition functions (or just functions, for short) are Crossplane extensions that template Crossplane resources. Crossplane calls the composition functions to determine what resources it should create when you create a composite resource (XR).</p><div class="admonition tip d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="tip:"><use xlink:href="#check"/></svg><span class=ps-1>Tip</span></div><div class=admonition-content><p>The Crossplane community has built lots of functions that let you template Crossplane resources using <a href=https://github.com/crossplane-contrib/function-cue>CUE</a>, <a href=https://github.com/crossplane-contrib/function-kcl>KCL</a>, Helm-like <a href=https://github.com/crossplane-contrib/function-go-templating>Go templates</a> or legacy Crossplane <a href=https://docs.crossplane.io/v1.18/guides/function-patch-and-transform/>Patch and Transforms</a>.</p><p>You can also <a href=#write-a-composition-function>write your own function</a> using Go or Python.</p></div></div><div class="admonition important d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="important:"><use xlink:href="#exclamation"/></svg><span class=ps-1>Important</span></div><div class=admonition-content><p>Crossplane has two modes of composition:</p><ul><li><code>mode: Pipeline</code></li><li><code>mode: Resources</code></li></ul><p>Use the <code>Pipeline</code> mode to use composition functions.</p><p>The <code>Resources</code> mode is deprecated, and you shouldn&rsquo;t use it. Crossplane supports Compositions that use the <code>Resources</code> mode for backward compatibility, but the feature is no longer maintained. Crossplane doesn&rsquo;t accept new <code>Resources</code> features, and only accepts security bug fixes.</p><p>See the <a href=https://docs.crossplane.io/v1.18/cli/command-reference/#beta-convert>CLI documentation</a> to learn how to use the <code>crossplane beta convert</code> command to convert a legacy <code>Resources</code> Composition to the <code>Pipeline</code> mode.</p></div></div><h3 id=install-a-composition-function>Install a composition function <a class=anchor-link id=install-a-composition-function href=#install-a-composition-function aria-label="Link to this section: Install a composition function"></a></h3><p>Installing a Function creates a function pod. Crossplane sends requests to this pod to ask it what resources to create when you create a composite resource.</p><p>Install a Function with a Crossplane <code><highlight-term id=1731573034653889211 data-label=install data-line=2>Function</highlight-term></code> object setting the <code><highlight-term id=1731573034653934927 data-label=install data-line=6>spec.package</highlight-term></code> value to the location of the function package.</p><p>For example, to install <a href=https://docs.crossplane.io/v1.18/guides/function-patch-and-transform/>Function Patch and Transform</a>,</p><div class=highlight label=install><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-1-1><a class=lnlinks href=#hl-1-1>1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>pkg.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-2><a class=lnlinks href=#hl-1-2>2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Function</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-3><a class=lnlinks href=#hl-1-3>3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-4><a class=lnlinks href=#hl-1-4>4</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>function-patch-and-transform</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-5><a class=lnlinks href=#hl-1-5>5</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-6><a class=lnlinks href=#hl-1-6>6</a></span><span class=cl><span class=w> </span><span class=nt>package</span><span class=p>:</span><span class=w> </span><span class=l>xpkg.upbound.io/crossplane-contrib/function-patch-and-transform:v0.1.4</span><span class=w> </span></span></span></code></pre></div><div class="admonition tip d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="tip:"><use xlink:href="#check"/></svg><span class=ps-1>Tip</span></div><div class=admonition-content>Functions are Crossplane Packages. Read more about Packages in the <a href=https://docs.crossplane.io/v1.18/concepts/packages/>Packages documentation</a>.</div></div><p>By default, the Function pod installs in the same namespace as Crossplane (<code>crossplane-system</code>).</p><h3 id=verify-a-composition-function>Verify a composition function <a class=anchor-link id=verify-a-composition-function href=#verify-a-composition-function aria-label="Link to this section: Verify a composition function"></a></h3><p>View the status of a Function with <code>kubectl get functions</code></p><p>During the install a Function reports <code>INSTALLED</code> as <code>True</code> and <code>HEALTHY</code> as <code>Unknown</code>.</p><div class=highlight copy-lines=1><pre tabindex=0 class=chroma><code class=language-shell data-lang=shell><span class=line><span class=ln id=hl-2-1><a class=lnlinks href=#hl-2-1>1</a></span><span class=cl>kubectl get functions </span></span><span class=line><span class=ln id=hl-2-2><a class=lnlinks href=#hl-2-2>2</a></span><span class=cl>NAME INSTALLED HEALTHY PACKAGE AGE </span></span><span class=line><span class=ln id=hl-2-3><a class=lnlinks href=#hl-2-3>3</a></span><span class=cl><span class=k>function</span>-patch-and-transform True Unknown xpkg.upbound.io/crossplane-contrib/function-patch-and-transform:v0.1.4 10s </span></span></code></pre></div><p>After the Function install completes and it&rsquo;s ready for use the <code>HEALTHY</code> status reports <code>True</code>.</p><h3 id=use-a-function-in-a-composition>Use a function in a composition <a class=anchor-link id=use-a-function-in-a-composition href=#use-a-function-in-a-composition aria-label="Link to this section: Use a function in a composition"></a></h3><p>Crossplane calls a Function to determine what resources it should create when you create a composite resource. The Function also tells Crossplane what to do with these resources when you update or delete a composite resource.</p><p>When Crossplane calls a Function it sends it the current state of the composite resource. It also sends it the current state of any managed resources the composite resource owns.</p><p>Crossplane knows what Function to call when a composite resource changes by looking at the Composition the composite resource uses.</p><p>To use composition functions set the Composition <code><highlight-term id=1731573034654066448 data-label=single data-line=6>mode</highlight-term></code> to <code><highlight-term id=1731573034654097955 data-label=single data-line=6>Pipeline</highlight-term></code>.</p><p>Define a <code><highlight-term id=1731573034654126288 data-label=single data-line=7>pipeline</highlight-term></code> of <code><highlight-term id=1731573034654154698 data-label=single data-line=8>steps</highlight-term></code>. Each <code><highlight-term id=1731573034654181907 data-label=single data-line=8>step</highlight-term></code> calls a Function.</p><p>Each <code><highlight-term id=1731573034654212821 data-label=single data-line=8>step</highlight-term></code> uses a <code><highlight-term id=1731573034654308419 data-label=single data-line=9>functionRef</highlight-term></code> to reference the <code><highlight-term id=1731573034654394757 data-label=single data-line=10>name</highlight-term></code> of the Function to call.</p><div class="admonition important d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="important:"><use xlink:href="#exclamation"/></svg><span class=ps-1>Important</span></div><div class=admonition-content><p>Compositions using <code><highlight-term id=1731573034654481771 data-label=single data-line=6>mode: Pipeline</highlight-term></code> can&rsquo;t specify resource templates with a <code>resources</code> field.</p><p>Use function &ldquo;Patch and Transform&rdquo; to create resource templates.</p></div></div><p>Some Functions also allow you to specify an <code><highlight-term id=1731573034654665527 data-label=single data-line=11>input</highlight-term></code>.<br>The function defines the <code><highlight-term id=1731573034654697541 data-label=single data-line=13>kind</highlight-term></code> of input.</p><p>This example uses <a href=https://docs.crossplane.io/v1.18/guides/function-patch-and-transform/>Function Patch and Transform</a>. Function Patch and Transform implements Crossplane resource templates.<br>The input kind is <code><highlight-term id=1731573034654898874 data-label=single data-line=13>Resources</highlight-term></code>, and it accepts <code><highlight-term id=1731573034654926096 data-label=single data-line=14>resources</highlight-term></code> as input.</p><div class=highlight label=single copy-lines=none><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-3-1><a class=lnlinks href=#hl-3-1> 1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>apiextensions.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-2><a class=lnlinks href=#hl-3-2> 2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Composition</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-3><a class=lnlinks href=#hl-3-3> 3</a></span><span class=cl><span class=w></span><span class=c># Removed for Brevity</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-4><a class=lnlinks href=#hl-3-4> 4</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-5><a class=lnlinks href=#hl-3-5> 5</a></span><span class=cl><span class=w> </span><span class=c># Removed for Brevity</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-6><a class=lnlinks href=#hl-3-6> 6</a></span><span class=cl><span class=w> </span><span class=nt>mode</span><span class=p>:</span><span class=w> </span><span class=l>Pipeline</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-7><a class=lnlinks href=#hl-3-7> 7</a></span><span class=cl><span class=w> </span><span class=nt>pipeline</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-8><a class=lnlinks href=#hl-3-8> 8</a></span><span class=cl><span class=w> </span>- <span class=nt>step</span><span class=p>:</span><span class=w> </span><span class=l>patch-and-transform</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-9><a class=lnlinks href=#hl-3-9> 9</a></span><span class=cl><span class=w> </span><span class=nt>functionRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-10><a class=lnlinks href=#hl-3-10>10</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>function-patch-and-transform</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-11><a class=lnlinks href=#hl-3-11>11</a></span><span class=cl><span class=w> </span><span class=nt>input</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-12><a class=lnlinks href=#hl-3-12>12</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>pt.fn.crossplane.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-13><a class=lnlinks href=#hl-3-13>13</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Resources</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-14><a class=lnlinks href=#hl-3-14>14</a></span><span class=cl><span class=w> </span><span class=nt>resources</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-15><a class=lnlinks href=#hl-3-15>15</a></span><span class=cl><span class=w> </span>- <span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>storage-bucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-16><a class=lnlinks href=#hl-3-16>16</a></span><span class=cl><span class=w> </span><span class=nt>base</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-17><a class=lnlinks href=#hl-3-17>17</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>s3.aws.upbound.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-18><a class=lnlinks href=#hl-3-18>18</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Bucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-19><a class=lnlinks href=#hl-3-19>19</a></span><span class=cl><span class=w> </span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-20><a class=lnlinks href=#hl-3-20>20</a></span><span class=cl><span class=w> </span><span class=nt>forProvider</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-21><a class=lnlinks href=#hl-3-21>21</a></span><span class=cl><span class=w> </span><span class=nt>region</span><span class=p>:</span><span class=w> </span><span class=s2>&#34;us-east-2&#34;</span><span class=w> </span></span></span></code></pre></div><h3 id=use-a-pipeline-of-functions-in-a-composition>Use a pipeline of functions in a composition <a class=anchor-link id=use-a-pipeline-of-functions-in-a-composition href=#use-a-pipeline-of-functions-in-a-composition aria-label="Link to this section: Use a pipeline of functions in a composition"></a></h3><p>Crossplane can ask more than one Function what to do when a composite resource changes. When a Composition has a pipeline of two or more steps, Crossplane calls them all. It calls them in the order they appear in the pipeline.</p><p>Crossplane passes each Function in the pipeline the result of the previous Function. This enables powerful combinations of Functions. In this example, Crossplane calls <code><highlight-term id=1731573034654953428 data-label=double data-line=10>function-cue</highlight-term></code> to create an S3 bucket. Crossplane then passes the bucket to <code><highlight-term id=1731573034654979782 data-label=double data-line=23>function-auto-ready</highlight-term></code>, which marks the composite resource as ready when the bucket becomes ready.</p><div class=highlight label=double copy-lines=none><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-4-1><a class=lnlinks href=#hl-4-1> 1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>apiextensions.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-2><a class=lnlinks href=#hl-4-2> 2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Composition</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-3><a class=lnlinks href=#hl-4-3> 3</a></span><span class=cl><span class=w></span><span class=c># Removed for Brevity</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-4><a class=lnlinks href=#hl-4-4> 4</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-5><a class=lnlinks href=#hl-4-5> 5</a></span><span class=cl><span class=w> </span><span class=c># Removed for Brevity</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-6><a class=lnlinks href=#hl-4-6> 6</a></span><span class=cl><span class=w> </span><span class=nt>mode</span><span class=p>:</span><span class=w> </span><span class=l>Pipeline</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-7><a class=lnlinks href=#hl-4-7> 7</a></span><span class=cl><span class=w> </span><span class=nt>pipeline</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-8><a class=lnlinks href=#hl-4-8> 8</a></span><span class=cl><span class=w> </span>- <span class=nt>step</span><span class=p>:</span><span class=w> </span><span class=l>cue-export-resources</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-9><a class=lnlinks href=#hl-4-9> 9</a></span><span class=cl><span class=w> </span><span class=nt>functionRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-10><a class=lnlinks href=#hl-4-10>10</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>function-cue</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-11><a class=lnlinks href=#hl-4-11>11</a></span><span class=cl><span class=w> </span><span class=nt>input</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-12><a class=lnlinks href=#hl-4-12>12</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>cue.fn.crossplane.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-13><a class=lnlinks href=#hl-4-13>13</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>CUEInput</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-14><a class=lnlinks href=#hl-4-14>14</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>storage-bucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-15><a class=lnlinks href=#hl-4-15>15</a></span><span class=cl><span class=w> </span><span class=nt>export</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-16><a class=lnlinks href=#hl-4-16>16</a></span><span class=cl><span class=w> </span><span class=nt>target</span><span class=p>:</span><span class=w> </span><span class=l>Resources</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-17><a class=lnlinks href=#hl-4-17>17</a></span><span class=cl><span class=w> </span><span class=nt>value</span><span class=p>:</span><span class=w> </span><span class=p>|</span><span class=sd> </span></span></span><span class=line><span class=ln id=hl-4-18><a class=lnlinks href=#hl-4-18>18</a></span><span class=cl><span class=sd> apiVersion: &#34;s3.aws.upbound.io/v1beta1&#34; </span></span></span><span class=line><span class=ln id=hl-4-19><a class=lnlinks href=#hl-4-19>19</a></span><span class=cl><span class=sd> kind: &#34;Bucket&#34; </span></span></span><span class=line><span class=ln id=hl-4-20><a class=lnlinks href=#hl-4-20>20</a></span><span class=cl><span class=sd> spec: forProvider: region: &#34;us-east-2&#34;</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-21><a class=lnlinks href=#hl-4-21>21</a></span><span class=cl><span class=w> </span>- <span class=nt>step</span><span class=p>:</span><span class=w> </span><span class=l>automatically-detect-readiness</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-22><a class=lnlinks href=#hl-4-22>22</a></span><span class=cl><span class=w> </span><span class=nt>functionRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-23><a class=lnlinks href=#hl-4-23>23</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>function-auto-ready</span><span class=w> </span></span></span></code></pre></div><h3 id=enable-composite-resources>Enable composite resources <a class=anchor-link id=enable-composite-resources href=#enable-composite-resources aria-label="Link to this section: Enable composite resources"></a></h3><p>A Composition is only a template defining how to create managed resources. A Composition limits which Composite Resources can use this template.</p><p>A Composition&rsquo;s <code><highlight-term id=1731573034655009744 data-label=typeref data-line=6>compositeTypeRef</highlight-term></code> defines which Composite Resource type can use this Composition.</p><div class="admonition note d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="note:"><use xlink:href="#info"/></svg><span class=ps-1>Note</span></div><div class=admonition-content>Read more about Composite Resources in the <a href=https://docs.crossplane.io/v1.18/concepts/composite-resources/>Composite Resources page</a>.</div></div><p>Inside a Composition&rsquo;s <code><highlight-term id=1731573034655117193 data-label=typeref data-line=5>spec</highlight-term></code> define the Composite Resource <code><highlight-term id=1731573034655221130 data-label=typeref data-line=7>apiVersion</highlight-term></code> and <code><highlight-term id=1731573034655361868 data-label=typeref data-line=8>kind</highlight-term></code> that the Composition allows to use this template.</p><div class=highlight label=typeref copy-lines=none><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-5-1><a class=lnlinks href=#hl-5-1>1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>apiextensions.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-5-2><a class=lnlinks href=#hl-5-2>2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Composition</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-5-3><a class=lnlinks href=#hl-5-3>3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-5-4><a class=lnlinks href=#hl-5-4>4</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>dynamodb-with-bucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-5-5><a class=lnlinks href=#hl-5-5>5</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-5-6><a class=lnlinks href=#hl-5-6>6</a></span><span class=cl><span class=w> </span><span class=nt>compositeTypeRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-5-7><a class=lnlinks href=#hl-5-7>7</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>custom-api.example.org/v1alpha1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-5-8><a class=lnlinks href=#hl-5-8>8</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>database</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-5-9><a class=lnlinks href=#hl-5-9>9</a></span><span class=cl><span class=w> </span><span class=c># Removed for brevity</span><span class=w> </span></span></span></code></pre></div><h3 id=store-connection-details>Store connection details <a class=anchor-link id=store-connection-details href=#store-connection-details aria-label="Link to this section: Store connection details"></a></h3><p>Some managed resources generate unique details like usernames, passwords, IP addresses, ports or other connection details.</p><p>When resources inside a Composition create connection details Crossplane creates a Kubernetes secret object for each managed resource generating connection details.</p><div class="admonition note d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="note:"><use xlink:href="#info"/></svg><span class=ps-1>Note</span></div><div class=admonition-content><p>This section discusses creating Kubernetes secrets.<br>Crossplane also supports using external secret stores like <a href=https://www.vaultproject.io/>HashiCorp Vault</a>.</p><p>Read the <a href=https://docs.crossplane.io/v1.18/guides/vault-as-secret-store/>external secrets store guide</a> for more information on using Crossplane with an external secret store.</p></div></div><h4 id=composite-resource-combined-secret>Composite resource combined secret <a class=anchor-link id=composite-resource-combined-secret href=#composite-resource-combined-secret aria-label="Link to this section: Composite resource combined secret"></a></h4><p>Crossplane can combine all the secrets generated by the resources inside a Composition into a single Kubernetes secret and optionally copy the secret object for claims.</p><p>Set the value of <code>writeConnectionSecretsToNamespace</code> to the namespace where Crossplane should store the combined secret object.</p><div class=highlight copy-lines=none label=writeConn><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-6-1><a class=lnlinks href=#hl-6-1>1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>apiextensions.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-6-2><a class=lnlinks href=#hl-6-2>2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Composition</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-6-3><a class=lnlinks href=#hl-6-3>3</a></span><span class=cl><span class=w></span><span class=c># Removed for Brevity</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-6-4><a class=lnlinks href=#hl-6-4>4</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-6-5><a class=lnlinks href=#hl-6-5>5</a></span><span class=cl><span class=w> </span><span class=nt>writeConnectionSecretsToNamespace</span><span class=p>:</span><span class=w> </span><span class=l>my-namespace</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-6-6><a class=lnlinks href=#hl-6-6>6</a></span><span class=cl><span class=w> </span><span class=nt>resources</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-6-7><a class=lnlinks href=#hl-6-7>7</a></span><span class=cl><span class=w> </span><span class=c># Removed for brevity</span><span class=w> </span></span></span></code></pre></div><h4 id=composed-resource-secrets>Composed resource secrets <a class=anchor-link id=composed-resource-secrets href=#composed-resource-secrets aria-label="Link to this section: Composed resource secrets"></a></h4><p>Inside the <code>spec</code> of each resource producing connection details, define the <code>writeConnectionSecretToRef</code>, with a <code>namespace</code> and <code>name</code> of the secret object for the resource.</p><p>If a <code>writeConnectionSecretToRef</code> isn&rsquo;t defined, Crossplane doesn&rsquo;t write any keys to the secret.</p><div class=highlight label=writeConnRes><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-7-1><a class=lnlinks href=#hl-7-1> 1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>apiextensions.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-2><a class=lnlinks href=#hl-7-2> 2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Composition</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-3><a class=lnlinks href=#hl-7-3> 3</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-4><a class=lnlinks href=#hl-7-4> 4</a></span><span class=cl><span class=w> </span><span class=nt>writeConnectionSecretsToNamespace</span><span class=p>:</span><span class=w> </span><span class=l>other-namespace</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-5><a class=lnlinks href=#hl-7-5> 5</a></span><span class=cl><span class=w> </span><span class=nt>mode</span><span class=p>:</span><span class=w> </span><span class=l>Pipeline</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-6><a class=lnlinks href=#hl-7-6> 6</a></span><span class=cl><span class=w> </span><span class=nt>pipeline</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-7><a class=lnlinks href=#hl-7-7> 7</a></span><span class=cl><span class=w> </span>- <span class=nt>step</span><span class=p>:</span><span class=w> </span><span class=l>patch-and-transform</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-8><a class=lnlinks href=#hl-7-8> 8</a></span><span class=cl><span class=w> </span><span class=nt>functionRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-9><a class=lnlinks href=#hl-7-9> 9</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>function-patch-and-transform</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-10><a class=lnlinks href=#hl-7-10>10</a></span><span class=cl><span class=w> </span><span class=nt>input</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-11><a class=lnlinks href=#hl-7-11>11</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>pt.fn.crossplane.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-12><a class=lnlinks href=#hl-7-12>12</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Resources</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-13><a class=lnlinks href=#hl-7-13>13</a></span><span class=cl><span class=w> </span><span class=nt>resources</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-14><a class=lnlinks href=#hl-7-14>14</a></span><span class=cl><span class=w> </span>- <span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>key</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-15><a class=lnlinks href=#hl-7-15>15</a></span><span class=cl><span class=w> </span><span class=nt>base</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-16><a class=lnlinks href=#hl-7-16>16</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>iam.aws.upbound.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-17><a class=lnlinks href=#hl-7-17>17</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>AccessKey</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-18><a class=lnlinks href=#hl-7-18>18</a></span><span class=cl><span class=w> </span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-19><a class=lnlinks href=#hl-7-19>19</a></span><span class=cl><span class=w> </span><span class=nt>forProvider</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-20><a class=lnlinks href=#hl-7-20>20</a></span><span class=cl><span class=w> </span><span class=c># Removed for brevity</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-21><a class=lnlinks href=#hl-7-21>21</a></span><span class=cl><span class=w> </span><span class=nt>writeConnectionSecretToRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-22><a class=lnlinks href=#hl-7-22>22</a></span><span class=cl><span class=w> </span><span class=nt>namespace</span><span class=p>:</span><span class=w> </span><span class=l>docs</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-7-23><a class=lnlinks href=#hl-7-23>23</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>key1</span><span class=w> </span></span></span></code></pre></div><p>Crossplane saves a secret with the <code>name</code> in the <code>namespace</code> provided.</p><div class=highlight label=viewComposedSec><pre tabindex=0 class=chroma><code class=language-shell data-lang=shell><span class=line><span class=ln id=hl-8-1><a class=lnlinks href=#hl-8-1>1</a></span><span class=cl>kubectl get secrets -n docs </span></span><span class=line><span class=ln id=hl-8-2><a class=lnlinks href=#hl-8-2>2</a></span><span class=cl>NAME TYPE DATA AGE </span></span><span class=line><span class=ln id=hl-8-3><a class=lnlinks href=#hl-8-3>3</a></span><span class=cl>key1 connection.crossplane.io/v1alpha1 <span class=m>4</span> 4m30s </span></span></code></pre></div><div class="admonition tip d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="tip:"><use xlink:href="#check"/></svg><span class=ps-1>Tip</span></div><div class=admonition-content>Remember to create a unique name for each secret.</div></div><h4 id=external-secret-stores>External secret stores <a class=anchor-link id=external-secret-stores href=#external-secret-stores aria-label="Link to this section: External secret stores"></a></h4><p>Crossplane <a href=https://docs.crossplane.io/v1.18/guides/vault-as-secret-store/>External Secret Stores</a> write secrets and connection details to external secret stores like HashiCorp Vault.</p><div class="admonition important d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="important:"><use xlink:href="#exclamation"/></svg><span class=ps-1>Important</span></div><div class=admonition-content><p>External Secret Stores are an alpha feature.</p><p>They&rsquo;re not recommended for production use. Crossplane disables External Secret Stores by default.</p></div></div><p>Use <code>publishConnectionDetailsWithStoreConfigRef</code> in place of <code>writeConnectionSecretsToNamespace</code> to define the <code>StoreConfig</code> to save connection details to.</p><p>For example, using a <code>StoreConfig</code> with the <code>name</code> &ldquo;vault,&rdquo; use <code>publishConnectionDetailsWithStoreConfigRef.name</code> matching the <code>StoreConfig.name</code>, in this example, &ldquo;vault.&rdquo;</p><div class=highlight label=gcp-storeconfig copy-lines=none><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-9-1><a class=lnlinks href=#hl-9-1> 1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>gcp.crossplane.io/v1alpha1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-9-2><a class=lnlinks href=#hl-9-2> 2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>StoreConfig</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-9-3><a class=lnlinks href=#hl-9-3> 3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-9-4><a class=lnlinks href=#hl-9-4> 4</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>vault</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-9-5><a class=lnlinks href=#hl-9-5> 5</a></span><span class=cl><span class=w></span><span class=c># Removed for brevity.</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-9-6><a class=lnlinks href=#hl-9-6> 6</a></span><span class=cl><span class=w></span><span class=nn>---</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-9-7><a class=lnlinks href=#hl-9-7> 7</a></span><span class=cl><span class=w></span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>apiextensions.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-9-8><a class=lnlinks href=#hl-9-8> 8</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Composition</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-9-9><a class=lnlinks href=#hl-9-9> 9</a></span><span class=cl><span class=w></span><span class=c># Removed for Brevity</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-9-10><a class=lnlinks href=#hl-9-10>10</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-9-11><a class=lnlinks href=#hl-9-11>11</a></span><span class=cl><span class=w> </span><span class=nt>publishConnectionDetailsWithStoreConfigRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-9-12><a class=lnlinks href=#hl-9-12>12</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>vault</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-9-13><a class=lnlinks href=#hl-9-13>13</a></span><span class=cl><span class=w> </span><span class=c># Removed for brevity</span><span class=w> </span></span></span></code></pre></div><p>For more details read the <a href=https://docs.crossplane.io/v1.18/guides/vault-as-secret-store/>External Secret Stores</a> integration guide.</p><h2 id=test-a-composition>Test a composition <a class=anchor-link id=test-a-composition href=#test-a-composition aria-label="Link to this section: Test a composition"></a></h2><p>You can preview the output of any composition using the Crossplane CLI. You don&rsquo;t need a Crossplane control plane to do this. The Crossplane CLI uses Docker Engine to run functions.</p><div class="admonition important d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="important:"><use xlink:href="#exclamation"/></svg><span class=ps-1>Important</span></div><div class=admonition-content>The <code>crossplane render</code> command only supports composition functions. It doesn&rsquo;t support <code>mode: Resources</code> Compositions.</div></div><div class="admonition tip d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="tip:"><use xlink:href="#check"/></svg><span class=ps-1>Tip</span></div><div class=admonition-content>See the <a href=https://docs.crossplane.io/v1.18/cli/>Crossplane CLI docs</a> to learn how to install and use the Crossplane CLI.</div></div><div class="admonition important d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="important:"><use xlink:href="#exclamation"/></svg><span class=ps-1>Important</span></div><div class=admonition-content>Running <code>crossplane render</code> requires <a href=https://www.docker.com>Docker</a>.</div></div><p>Provide a composite resource, composition and composition functions to render the output locally.</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-shell data-lang=shell><span class=line><span class=ln id=hl-10-1><a class=lnlinks href=#hl-10-1>1</a></span><span class=cl>crossplane render xr.yaml composition.yaml functions.yaml </span></span></code></pre></div><p><code>crossplane render</code> prints resources as YAML to stdout. It prints the composite resource first, followed by the resources the composition functions created.</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-11-1><a class=lnlinks href=#hl-11-1> 1</a></span><span class=cl><span class=nn>---</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-2><a class=lnlinks href=#hl-11-2> 2</a></span><span class=cl><span class=w></span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>example.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-3><a class=lnlinks href=#hl-11-3> 3</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>XBucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-4><a class=lnlinks href=#hl-11-4> 4</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-5><a class=lnlinks href=#hl-11-5> 5</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>example-render</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-6><a class=lnlinks href=#hl-11-6> 6</a></span><span class=cl><span class=w></span><span class=nn>---</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-7><a class=lnlinks href=#hl-11-7> 7</a></span><span class=cl><span class=w></span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>s3.aws.upbound.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-8><a class=lnlinks href=#hl-11-8> 8</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Bucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-9><a class=lnlinks href=#hl-11-9> 9</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-10><a class=lnlinks href=#hl-11-10>10</a></span><span class=cl><span class=w> </span><span class=nt>annotations</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-11><a class=lnlinks href=#hl-11-11>11</a></span><span class=cl><span class=w> </span><span class=nt>crossplane.io/composition-resource-name</span><span class=p>:</span><span class=w> </span><span class=l>storage-bucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-12><a class=lnlinks href=#hl-11-12>12</a></span><span class=cl><span class=w> </span><span class=nt>generateName</span><span class=p>:</span><span class=w> </span><span class=l>example-render-</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-13><a class=lnlinks href=#hl-11-13>13</a></span><span class=cl><span class=w> </span><span class=nt>labels</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-14><a class=lnlinks href=#hl-11-14>14</a></span><span class=cl><span class=w> </span><span class=nt>crossplane.io/composite</span><span class=p>:</span><span class=w> </span><span class=l>example-render</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-15><a class=lnlinks href=#hl-11-15>15</a></span><span class=cl><span class=w> </span><span class=nt>ownerReferences</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-16><a class=lnlinks href=#hl-11-16>16</a></span><span class=cl><span class=w> </span>- <span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>example.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-17><a class=lnlinks href=#hl-11-17>17</a></span><span class=cl><span class=w> </span><span class=nt>blockOwnerDeletion</span><span class=p>:</span><span class=w> </span><span class=kc>true</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-18><a class=lnlinks href=#hl-11-18>18</a></span><span class=cl><span class=w> </span><span class=nt>controller</span><span class=p>:</span><span class=w> </span><span class=kc>true</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-19><a class=lnlinks href=#hl-11-19>19</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>XBucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-20><a class=lnlinks href=#hl-11-20>20</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>example-render</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-21><a class=lnlinks href=#hl-11-21>21</a></span><span class=cl><span class=w> </span><span class=nt>uid</span><span class=p>:</span><span class=w> </span><span class=s2>&#34;&#34;</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-22><a class=lnlinks href=#hl-11-22>22</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-23><a class=lnlinks href=#hl-11-23>23</a></span><span class=cl><span class=w> </span><span class=nt>forProvider</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-11-24><a class=lnlinks href=#hl-11-24>24</a></span><span class=cl><span class=w> </span><span class=nt>region</span><span class=p>:</span><span class=w> </span><span class=l>us-east-2</span><span class=w> </span></span></span></code></pre></div><div class="accordion mb-3" id=the-xryaml-compositionyaml-and-functionyaml-files-used-in-the-example-1958-Parent><div class=accordion-item><h2 class=accordion-header id=the-xryaml-compositionyaml-and-functionyaml-files-used-in-the-example-1958><button class="accordion-button collapsed" type=button data-bs-toggle=collapse data-bs-target=#the-xryaml-compositionyaml-and-functionyaml-files-used-in-the-example-1958-Content aria-expanded=false aria-controls=the-xryaml-compositionyaml-and-functionyaml-files-used-in-the-example-1958-Content> The xr.yaml, composition.yaml and function.yaml files used in the example</button></h2><div id=the-xryaml-compositionyaml-and-functionyaml-files-used-in-the-example-1958-Content class="accordion-collapse collapse" aria-labelledby=the-xryaml-compositionyaml-and-functionyaml-files-used-in-the-example-1958 data-bs-parent=#the-xryaml-compositionyaml-and-functionyaml-files-used-in-the-example-1958-Parent><div class="accordion-body rounded-bottom"><p>You can recreate the output below by running <code>crossplane render</code> with these files.</p><p>The <code>xr.yaml</code> file contains the composite resource to render:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-0-1><a class=lnlinks href=#hl-0-1>1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>example.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-2><a class=lnlinks href=#hl-0-2>2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>XBucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-3><a class=lnlinks href=#hl-0-3>3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-4><a class=lnlinks href=#hl-0-4>4</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>example-render</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-5><a class=lnlinks href=#hl-0-5>5</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-6><a class=lnlinks href=#hl-0-6>6</a></span><span class=cl><span class=w> </span><span class=nt>bucketRegion</span><span class=p>:</span><span class=w> </span><span class=l>us-east-2</span><span class=w> </span></span></span></code></pre></div><p>The <code>composition.yaml</code> file contains the Composition to use to render the composite resource:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-1-1><a class=lnlinks href=#hl-1-1> 1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>apiextensions.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-2><a class=lnlinks href=#hl-1-2> 2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Composition</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-3><a class=lnlinks href=#hl-1-3> 3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-4><a class=lnlinks href=#hl-1-4> 4</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>example-render</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-5><a class=lnlinks href=#hl-1-5> 5</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-6><a class=lnlinks href=#hl-1-6> 6</a></span><span class=cl><span class=w> </span><span class=nt>compositeTypeRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-7><a class=lnlinks href=#hl-1-7> 7</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>example.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-8><a class=lnlinks href=#hl-1-8> 8</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>XBucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-9><a class=lnlinks href=#hl-1-9> 9</a></span><span class=cl><span class=w> </span><span class=nt>mode</span><span class=p>:</span><span class=w> </span><span class=l>Pipeline</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-10><a class=lnlinks href=#hl-1-10>10</a></span><span class=cl><span class=w> </span><span class=nt>pipeline</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-11><a class=lnlinks href=#hl-1-11>11</a></span><span class=cl><span class=w> </span>- <span class=nt>step</span><span class=p>:</span><span class=w> </span><span class=l>patch-and-transform</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-12><a class=lnlinks href=#hl-1-12>12</a></span><span class=cl><span class=w> </span><span class=nt>functionRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-13><a class=lnlinks href=#hl-1-13>13</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>function-patch-and-transform</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-14><a class=lnlinks href=#hl-1-14>14</a></span><span class=cl><span class=w> </span><span class=nt>input</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-15><a class=lnlinks href=#hl-1-15>15</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>pt.fn.crossplane.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-16><a class=lnlinks href=#hl-1-16>16</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Resources</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-17><a class=lnlinks href=#hl-1-17>17</a></span><span class=cl><span class=w> </span><span class=nt>resources</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-18><a class=lnlinks href=#hl-1-18>18</a></span><span class=cl><span class=w> </span>- <span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>storage-bucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-19><a class=lnlinks href=#hl-1-19>19</a></span><span class=cl><span class=w> </span><span class=nt>base</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-20><a class=lnlinks href=#hl-1-20>20</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>s3.aws.upbound.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-21><a class=lnlinks href=#hl-1-21>21</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Bucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-22><a class=lnlinks href=#hl-1-22>22</a></span><span class=cl><span class=w> </span><span class=nt>patches</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-23><a class=lnlinks href=#hl-1-23>23</a></span><span class=cl><span class=w> </span>- <span class=nt>type</span><span class=p>:</span><span class=w> </span><span class=l>FromCompositeFieldPath</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-24><a class=lnlinks href=#hl-1-24>24</a></span><span class=cl><span class=w> </span><span class=nt>fromFieldPath</span><span class=p>:</span><span class=w> </span><span class=l>spec.bucketRegion</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-25><a class=lnlinks href=#hl-1-25>25</a></span><span class=cl><span class=w> </span><span class=nt>toFieldPath</span><span class=p>:</span><span class=w> </span><span class=l>spec.forProvider.region</span><span class=w> </span></span></span></code></pre></div><p>The <code>functions.yaml</code> file contains the Functions the Composition references in its pipeline steps:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-2-1><a class=lnlinks href=#hl-2-1>1</a></span><span class=cl><span class=nn>---</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-2><a class=lnlinks href=#hl-2-2>2</a></span><span class=cl><span class=w></span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>pkg.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-3><a class=lnlinks href=#hl-2-3>3</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Function</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-4><a class=lnlinks href=#hl-2-4>4</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-5><a class=lnlinks href=#hl-2-5>5</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>function-patch-and-transform</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-6><a class=lnlinks href=#hl-2-6>6</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-7><a class=lnlinks href=#hl-2-7>7</a></span><span class=cl><span class=w> </span><span class=nt>package</span><span class=p>:</span><span class=w> </span><span class=l>xpkg.upbound.io/crossplane-contrib/function-patch-and-transform:v0.1.4</span><span class=w> </span></span></span></code></pre></div></div></div></div></div><p>The Crossplane CLI uses Docker Engine to run functions. You can change how the Crossplane CLI runs a function by adding an annotation in <code>functions.yaml</code>. Add the <code>render.crossplane.io/runtime</code> annotation to a Function to change how it&rsquo;s run.</p><p><code>crossplane render</code> supports two <code>render.crossplane.io/runtime</code> values:</p><ul><li><code>Docker</code> (the default) connects to Docker Engine. It uses Docker to pull and run a function runtime.</li><li><code>Development</code> connects to a function runtime you have run manually.</li></ul><p>When you use the <code><highlight-term id=1731573034657369154 data-label=development data-line=6>Development</highlight-term></code> runtime the Crossplane CLI ignores the Function&rsquo;s <code><highlight-term id=1731573034657417685 data-label=development data-line=8>package</highlight-term></code>. Instead it expects you to make sure the function is listening on localhost port 9443. The function must be listening without gRPC transport security. Most function SDKs let you run a function with the <code>--insecure</code> flag to disable transport security. For example you can run a Go function locally using <code>go run . --insecure</code>.</p><div class=highlight label=development><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-12-1><a class=lnlinks href=#hl-12-1>1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>pkg.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-12-2><a class=lnlinks href=#hl-12-2>2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Function</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-12-3><a class=lnlinks href=#hl-12-3>3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-12-4><a class=lnlinks href=#hl-12-4>4</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>function-patch-and-transform</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-12-5><a class=lnlinks href=#hl-12-5>5</a></span><span class=cl><span class=w> </span><span class=nt>annotations</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-12-6><a class=lnlinks href=#hl-12-6>6</a></span><span class=cl><span class=w> </span><span class=nt>render.crossplane.io/runtime</span><span class=p>:</span><span class=w> </span><span class=l>Development</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-12-7><a class=lnlinks href=#hl-12-7>7</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-12-8><a class=lnlinks href=#hl-12-8>8</a></span><span class=cl><span class=w> </span><span class=nt>package</span><span class=p>:</span><span class=w> </span><span class=l>xpkg.upbound.io/crossplane-contrib/function-patch-and-transform:v0.1.4</span><span class=w> </span></span></span></code></pre></div><div class="admonition tip d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="tip:"><use xlink:href="#check"/></svg><span class=ps-1>Tip</span></div><div class=admonition-content>Use the <code>Development</code> runtime when you <a href=#write-a-composition-function>write a composition function</a> to test your function end-to-end.</div></div><p><code>crossplane render</code> also supports the following Function annotations. These annotations affect how it runs Functions:</p><ul><li><code>render.crossplane.io/runtime-docker-cleanup</code> - When using the <code>Docker</code> runtime this annotation specifies whether the CLI should stop the function container after it calls the function. It supports the values <code>Stop</code>, to stop the container, and <code>Orphan</code>, to leave it running.</li><li><code>render.crossplane.io/runtime-docker-pull-policy</code> - When using the <code>Docker</code> runtime this annotation specifies when the CLI should pull the Function&rsquo;s package. It supports the values <code>Always</code>, <code>Never</code>, and <code>IfNotPresent</code>.</li><li><code>render.crossplane.io/runtime-development-target</code> - When using the <code>Development</code> runtime this annotation tells the CLI to connect to a Function running at the specified target. It uses <a href=https://github.com/grpc/grpc/blob/v1.59.1/doc/naming.md>gRPC target syntax</a>.</li></ul><h2 id=verify-a-composition>Verify a Composition <a class=anchor-link id=verify-a-composition href=#verify-a-composition aria-label="Link to this section: Verify a Composition"></a></h2><p>View all available Compositions with <code>kubectl get composition</code>.</p><div class=highlight copy-lines=1><pre tabindex=0 class=chroma><code class=language-shell data-lang=shell><span class=line><span class=ln id=hl-13-1><a class=lnlinks href=#hl-13-1>1</a></span><span class=cl>kubectl get composition </span></span><span class=line><span class=ln id=hl-13-2><a class=lnlinks href=#hl-13-2>2</a></span><span class=cl>NAME XR-KIND XR-APIVERSION AGE </span></span><span class=line><span class=ln id=hl-13-3><a class=lnlinks href=#hl-13-3>3</a></span><span class=cl>xapps.aws.platformref.upbound.io XApp aws.platformref.upbound.io/v1alpha1 123m </span></span><span class=line><span class=ln id=hl-13-4><a class=lnlinks href=#hl-13-4>4</a></span><span class=cl>xclusters.aws.platformref.upbound.io XCluster aws.platformref.upbound.io/v1alpha1 123m </span></span><span class=line><span class=ln id=hl-13-5><a class=lnlinks href=#hl-13-5>5</a></span><span class=cl>xeks.aws.platformref.upbound.io XEKS aws.platformref.upbound.io/v1alpha1 123m </span></span><span class=line><span class=ln id=hl-13-6><a class=lnlinks href=#hl-13-6>6</a></span><span class=cl>xnetworks.aws.platformref.upbound.io XNetwork aws.platformref.upbound.io/v1alpha1 123m </span></span><span class=line><span class=ln id=hl-13-7><a class=lnlinks href=#hl-13-7>7</a></span><span class=cl>xservices.aws.platformref.upbound.io XServices aws.platformref.upbound.io/v1alpha1 123m </span></span><span class=line><span class=ln id=hl-13-8><a class=lnlinks href=#hl-13-8>8</a></span><span class=cl>xsqlinstances.aws.platformref.upbound.io XSQLInstance aws.platformref.upbound.io/v1alpha1 123m </span></span></code></pre></div><p>The <code>XR-KIND</code> lists the Composite Resource <code>kind</code> that&rsquo;s allowed to use the Composition template.<br>The <code>XR-APIVERSION</code> lists the Composite Resource API versions allowed to use the Composition template.</p><div class="admonition note d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="note:"><use xlink:href="#info"/></svg><span class=ps-1>Note</span></div><div class=admonition-content><p>The output of <code>kubectl get composition</code> is different than <code>kubectl get composite</code>.</p><p><code>kubectl get composition</code> lists all available Compositions.</p><p><code>kubectl get composite</code> lists all created Composite Resources and their related Composition.</p></div></div><h2 id=composition-validation>Composition validation <a class=anchor-link id=composition-validation href=#composition-validation aria-label="Link to this section: Composition validation"></a></h2><p>When creating a Composition, Crossplane automatically validates its integrity, checking that the Composition is well formed, for example:</p><p>If using <code>mode: Resources</code>:</p><ul><li>The <code>resources</code> field isn&rsquo;t empty.</li><li>All resources either use a <code>name</code> or don&rsquo;t. Compositions can&rsquo;t use both named and unnamed resources.</li><li>No duplicate resource names.</li><li>Patch sets must have names.</li><li>Patches that require a <code>fromFieldPath</code> value provide it.</li><li>Patches that require a <code>toFieldPath</code> value provide it.</li><li>Patches that require a <code>combine</code> field provide it.</li><li>Readiness checks using <code>matchString</code> aren&rsquo;t empty.</li><li>Readiness checks using <code>matchInteger</code> isn&rsquo;t <code>0</code>.</li><li>Readiness checks requiring a <code>fieldPath</code> value provide it.</li></ul><p>If using <code>mode: Pipeline</code> (Composition Functions):</p><ul><li>The <code>pipeline</code> field isn&rsquo;t empty.</li><li>No duplicate step names.</li></ul><h3 id=composition-schema-aware-validation>Composition schema aware validation <a class=anchor-link id=composition-schema-aware-validation href=#composition-schema-aware-validation aria-label="Link to this section: Composition schema aware validation"></a></h3><p>Crossplane also performs schema aware validation of Compositions. Schema validation checks that <code>patches</code>, <code>readinessChecks</code> and <code>connectionDetails</code> are valid according to the resource schemas. For example, checking that the source and destination fields of a patch are valid according to the source and destination resource schema.</p><div class="admonition note d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="note:"><use xlink:href="#info"/></svg><span class=ps-1>Note</span></div><div class=admonition-content><p>Composition schema aware validation is a beta feature. Crossplane enables beta features by default.</p><p>Disable schema aware validation by setting the <code>--enable-composition-webhook-schema-validation=false</code> flag on the Crossplane pod.</p><p>The <a href=https://docs.crossplane.io/v1.18/concepts/pods/#edit-the-deployment>Crossplane Pods</a> page has more information on enabling Crossplane flags.</p></div></div><h4 id=schema-aware-validation-modes>Schema aware validation modes <a class=anchor-link id=schema-aware-validation-modes href=#schema-aware-validation-modes aria-label="Link to this section: Schema aware validation modes"></a></h4><p>Crossplane always rejects Compositions in case of integrity errors.</p><p>Set the schema aware validation mode to configure how Crossplane handles both missing resource schemas and schema aware validation errors.</p><div class="admonition note d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="note:"><use xlink:href="#info"/></svg><span class=ps-1>Note</span></div><div class=admonition-content>If a resource schema is missing, Crossplane skips schema aware validation but still returns an error for integrity errors and a warning or an error for the missing schemas.</div></div><p>The following modes are available:</p><div class="table-responsive border rounded"><table class="table table-sm table-striped"><thead><tr><th>Mode</th><th>Missing Schema</th><th>Schema Aware Error</th><th>Integrity Error</th></tr></thead><tbody><tr><td><code>warn</code></td><td>Warning</td><td>Warning</td><td>Error</td></tr><tr><td><code>loose</code></td><td>Warning</td><td>Error</td><td>Error</td></tr><tr><td><code>strict</code></td><td>Error</td><td>Error</td><td>Error</td></tr></tbody></table></div><p>Change the validation mode for a Composition with the <code><highlight-term id=1731573034657873917 data-label=mode data-line=5>crossplane.io/composition-schema-aware-validation-mode</highlight-term></code> annotation.</p><p>If not specified, the default mode is <code>warn</code>.</p><p>For example, to enable <code>loose</code> mode checking set the annotation value to <code><highlight-term id=1731573034657924353 data-label=mode data-line=5>loose</highlight-term></code>.</p><div class=highlight copy-lines=none label=mode><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-14-1><a class=lnlinks href=#hl-14-1>1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>apiextensions.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-14-2><a class=lnlinks href=#hl-14-2>2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Composition</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-14-3><a class=lnlinks href=#hl-14-3>3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-14-4><a class=lnlinks href=#hl-14-4>4</a></span><span class=cl><span class=w> </span><span class=nt>annotations</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-14-5><a class=lnlinks href=#hl-14-5>5</a></span><span class=cl><span class=w> </span><span class=nt>crossplane.io/composition-schema-aware-validation-mode</span><span class=p>:</span><span class=w> </span><span class=l>loose</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-14-6><a class=lnlinks href=#hl-14-6>6</a></span><span class=cl><span class=w> </span><span class=c># Removed for brevity</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-14-7><a class=lnlinks href=#hl-14-7>7</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-14-8><a class=lnlinks href=#hl-14-8>8</a></span><span class=cl><span class=w> </span><span class=c># Removed for brevity</span><span class=w> </span></span></span></code></pre></div><div class="admonition important d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="important:"><use xlink:href="#exclamation"/></svg><span class=ps-1>Important</span></div><div class=admonition-content><p>Validation modes also apply to Compositions defined by Configuration packages.</p><p>Depending on the mode configured in the Composition, schema aware validation issues may result in warnings or the rejection of the Composition.</p><p>View the Crossplane logs for validation warnings.</p><p>Crossplane sets a Configuration as unhealthy if there are validation errors. View the Configuration details with <code>kubectl describe configuration</code> to see the specific errors.</p></div></div><h2 id=write-a-composition-function>Write a composition function <a class=anchor-link id=write-a-composition-function href=#write-a-composition-function aria-label="Link to this section: Write a composition function"></a></h2><p>Composition functions let you replace complicated Compositions with code written in your programming language of choice. Crossplane has tools, software development kits (SDKs) and templates to help you write a function.</p><p>Here&rsquo;s an example of a tiny, hello world function. This example is written in <a href=https://go.dev>Go</a>.</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-go data-lang=go><span class=line><span class=ln id=hl-15-1><a class=lnlinks href=#hl-15-1>1</a></span><span class=cl><span class=kd>func</span> <span class=p>(</span><span class=nx>f</span> <span class=o>*</span><span class=nx>Function</span><span class=p>)</span> <span class=nf>RunFunction</span><span class=p>(</span><span class=nx>_</span> <span class=nx>context</span><span class=p>.</span><span class=nx>Context</span><span class=p>,</span> <span class=nx>req</span> <span class=o>*</span><span class=nx>fnv1</span><span class=p>.</span><span class=nx>RunFunctionRequest</span><span class=p>)</span> <span class=p>(</span><span class=o>*</span><span class=nx>fnv1</span><span class=p>.</span><span class=nx>RunFunctionResponse</span><span class=p>,</span> <span class=kt>error</span><span class=p>)</span> <span class=p>{</span> </span></span><span class=line><span class=ln id=hl-15-2><a class=lnlinks href=#hl-15-2>2</a></span><span class=cl> <span class=nx>rsp</span> <span class=o>:=</span> <span class=nx>response</span><span class=p>.</span><span class=nf>To</span><span class=p>(</span><span class=nx>req</span><span class=p>,</span> <span class=nx>response</span><span class=p>.</span><span class=nx>DefaultTTL</span><span class=p>)</span> </span></span><span class=line><span class=ln id=hl-15-3><a class=lnlinks href=#hl-15-3>3</a></span><span class=cl> <span class=nx>response</span><span class=p>.</span><span class=nf>Normal</span><span class=p>(</span><span class=nx>rsp</span><span class=p>,</span> <span class=s>&#34;Hello world!&#34;</span><span class=p>)</span> </span></span><span class=line><span class=ln id=hl-15-4><a class=lnlinks href=#hl-15-4>4</a></span><span class=cl> <span class=k>return</span> <span class=nx>rsp</span><span class=p>,</span> <span class=kc>nil</span> </span></span><span class=line><span class=ln id=hl-15-5><a class=lnlinks href=#hl-15-5>5</a></span><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>Crossplane has <a href=https://docs.crossplane.io/v1.18/guides/>language specific guides</a> to writing a composition function. Refer to the guide for your preferred language to learn how to write a composition function.</p><p>When you&rsquo;re writing a composition function it&rsquo;s useful to know how composition functions work. Read the next section to learn <a href=#how-composition-functions-work>how composition functions work</a>.</p><h2 id=how-composition-functions-work>How composition functions work <a class=anchor-link id=how-composition-functions-work href=#how-composition-functions-work aria-label="Link to this section: How composition functions work"></a></h2><p>Each composition function is actually a <a href=https://grpc.io>gRPC</a> server. gRPC is a high performance, open source remote procedure call (RPC) framework. When you <a href=#install-a-composition-function>install a function</a> Crossplane deploys the function as a gRPC server. Crossplane encrypts and authenticates all gRPC communication.</p><p>You don&rsquo;t have to be a gRPC expert to write a function. Crossplane&rsquo;s function SDKs setup gRPC for you. It&rsquo;s useful to understand how Crossplane calls your function though, and how your function should respond.</p><pre class=mermaid>sequenceDiagram User->>+API Server: Create composite resource Crossplane Pod->>+API Server: Observe composite resource Crossplane Pod->>+Function Pod: gRPC RunFunctionRequest Function Pod->>+Crossplane Pod: gRPC RunFunctionResponse loop Extra resources needed? Crossplane Pod->>+API Server: Get Extra resources Crossplane Pod->>+Function Pod: gRPC RunFunctionRequest Function Pod->>+Crossplane Pod: gRPC RunFunctionResponse end Crossplane Pod->>+API Server: Apply desired composed resources </pre><p>When you create, update, or delete a composite resource that uses composition functions Crossplane calls each function in the order they appear in the Composition&rsquo;s pipeline. Crossplane calls each function by sending it a gRPC RunFunctionRequest. The function must respond with a gRPC RunFunctionResponse.</p><div class="admonition tip d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="tip:"><use xlink:href="#check"/></svg><span class=ps-1>Tip</span></div><div class=admonition-content>You can find detailed schemas for the RunFunctionRequest and RunFunctionResponse RPCs in the <a href=https://buf.build/crossplane/crossplane/docs/main:apiextensions.fn.proto.v1beta1>Buf Schema Registry</a>.</div></div><p>When Crossplane calls a function the first time it includes four important things in the RunFunctionRequest.</p><ol><li>The <strong>observed state</strong> of the composite resource, and any composed resources.</li><li>The <strong>desired state</strong> of the composite resource, and any composed resources.</li><li>The function&rsquo;s <strong>input</strong>.</li><li>The function pipeline&rsquo;s <strong>context</strong>.</li></ol><p>A function&rsquo;s main job is to update the <strong>desired state</strong> and return it to Crossplane. It does this by returning a RunFunctionResponse.</p><p>Most composition functions read the observed state of the composite resource, and use it to add composed resources to the desired state. This tells Crossplane which composed resources it should create or update.</p><p>If the function needs <strong>extra resources</strong> to determine the desired state it can request any cluster-scoped resource Crossplane already has access to, either by by name or labels through the returned RunFunctionResponse. Crossplane then calls the function again including the requested <strong>extra resources</strong> and the <strong>context</strong> returned by the Function itself alongside the same <strong>input</strong>, <strong>observed</strong> and <strong>desired state</strong> of the previous RunFunctionRequest. Functions can iteratively request <strong>extra resources</strong> if needed, but to avoid endlessly looping Crossplane limits the number of iterations to 5. Crossplane considers the function satisfied as soon as the <strong>extra resources</strong> requests become stable, so the Function returns the same exact request two times in a row. Crossplane errors if stability isn&rsquo;t reached after 5 iterations.</p><div class="admonition tip d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="tip:"><use xlink:href="#check"/></svg><span class=ps-1>Tip</span></div><div class=admonition-content><p>A <em>composed</em> resource is a resource created by a composite resource. Composed resources are usually Crossplane managed resources (MRs), but they can be any kind of Crossplane resource. For example a composite resource could also create a ProviderConfig, or another kind of composite resource.</p></div></div><h3 id=observed-state>Observed state <a class=anchor-link id=observed-state href=#observed-state aria-label="Link to this section: Observed state"></a></h3><p>When you create a composite resource like this one, Crossplane <em>observes</em> it and sends it to the composition function as part of the observed state.</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-17-1><a class=lnlinks href=#hl-17-1>1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>example.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-17-2><a class=lnlinks href=#hl-17-2>2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>XBucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-17-3><a class=lnlinks href=#hl-17-3>3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-17-4><a class=lnlinks href=#hl-17-4>4</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>example-render</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-17-5><a class=lnlinks href=#hl-17-5>5</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-17-6><a class=lnlinks href=#hl-17-6>6</a></span><span class=cl><span class=w> </span><span class=nt>bucketRegion</span><span class=p>:</span><span class=w> </span><span class=l>us-east-2</span><span class=w> </span></span></span></code></pre></div><p>If any composed resources already exist, Crossplane observes them and sends them to your function as part of the observed state.</p><p>Crossplane also observes the connection details of your composite resource and any composed resources. It sends them to your function as part of the observed state.</p><p>Crossplane observes the composite resource and any composed resources once, right before it starts calling the functions in the pipeline. This means that Crossplane sends every function in the pipeline the same observed state.</p><h3 id=desired-state>Desired state <a class=anchor-link id=desired-state href=#desired-state aria-label="Link to this section: Desired state"></a></h3><p>Desired state is the set of the changes the function pipeline wants to make to the composite resource and any composed resources. When a function adds composed resources to the desired state Crossplane creates them.</p><p>A function can change:</p><ul><li>The <code>status</code> of the composite resource.</li><li>The <code>metadata</code> and <code>spec</code> of any composed resource.</li></ul><p>A function can also change the connection details and readiness of the composite resource. A function indicates that the composite resource is ready by telling Crossplane whether its composed resources are ready. When the function pipeline tells Crossplane that all composed resources are ready, Crossplane marks the composite resource as ready.</p><p>A function can&rsquo;t change:</p><ul><li>The <code>metadata</code> or <code>spec</code> of the composite resource.</li><li>The <code>status</code> of any composed resource.</li><li>The connection details of any composed resource.</li></ul><p>A pipeline of functions <em>accumulates</em> desired state. This means that each function builds upon the desired state of previous functions in the pipeline. Crossplane sends a function the desired state accumulated by all previous functions in the pipeline. The function adds to or updates the desired state and then passes it on. When the last function in the pipeline has run, Crossplane applies the desired state it returns.</p><div class="admonition important d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="important:"><use xlink:href="#exclamation"/></svg><span class=ps-1>Important</span></div><div class=admonition-content><p>A function <strong>must</strong> copy all desired state from its RunFunctionRequest to its RunFunctionResponse. If a function adds a resource to its desired state the next function must copy it to its desired state. If it doesn&rsquo;t, Crossplane doesn&rsquo;t apply the resource. If the resource exists, Crossplane deletes it.</p><p>A function can <em>intentionally</em> choose not to copy parts of the desired state. For example a function may choose not to copy a desired resource to prevent that resource from existing.</p><p>Most function SDKs handle copying desired state automatically.</p></div></div><p>A function should only add the fields it cares about to the desired state. It should add these fields every time Crossplane calls it. If a function adds a field to the desired state once, but doesn&rsquo;t add it the next time it&rsquo;s called, Crossplane deletes the field. The same is true for composed resources. If a function adds a composed resource to the desired state, but doesn&rsquo;t add it the next time it&rsquo;s called, Crossplane deletes the composed resource.</p><div class="admonition tip d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="tip:"><use xlink:href="#check"/></svg><span class=ps-1>Tip</span></div><div class=admonition-content>Crossplane uses <a href=https://kubernetes.io/docs/reference/using-api/server-side-apply/>server side apply</a> to apply the desired state returned by a function pipeline. In server side apply terminology, the desired state is a <em>fully specified intent</em>.</div></div><p>For example, if all a function wants is to make sure an S3 bucket in region <code>us-east-2</code> exists, it should add this resource to its desired composed resources.</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-18-1><a class=lnlinks href=#hl-18-1>1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>s3.aws.upbound.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-18-2><a class=lnlinks href=#hl-18-2>2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Bucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-18-3><a class=lnlinks href=#hl-18-3>3</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-18-4><a class=lnlinks href=#hl-18-4>4</a></span><span class=cl><span class=w> </span><span class=nt>forProvider</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-18-5><a class=lnlinks href=#hl-18-5>5</a></span><span class=cl><span class=w> </span><span class=nt>region</span><span class=p>:</span><span class=w> </span><span class=l>us-east-2</span><span class=w> </span></span></span></code></pre></div><p>Even if the Bucket already exists and has other <code>spec</code> fields, or a <code>status</code>, <code>name</code>, <code>labels</code>, etc the function should omit them. The function should only include the fields it has an opinion about. Crossplane takes care of applying the fields the function cares about, merging them with the existing Bucket.</p><div class="admonition tip d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="tip:"><use xlink:href="#check"/></svg><span class=ps-1>Tip</span></div><div class=admonition-content>Composition functions don&rsquo;t actually use YAML for desired and observed resources. This example uses YAML for illustration purposes only.</div></div><h3 id=function-input>Function input <a class=anchor-link id=function-input href=#function-input aria-label="Link to this section: Function input"></a></h3><p>If a Composition includes <code><highlight-term id=1731573034658398954 data-label=input data-line=14>input</highlight-term></code> Crossplane sends it to the function. Input is a useful way to provide extra configuration to a function. Supporting input is optional. Not all functions support input.</p><div class=highlight label=input copy-lines=none><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-19-1><a class=lnlinks href=#hl-19-1> 1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>apiextensions.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-2><a class=lnlinks href=#hl-19-2> 2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Composition</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-3><a class=lnlinks href=#hl-19-3> 3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-4><a class=lnlinks href=#hl-19-4> 4</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>example-render</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-5><a class=lnlinks href=#hl-19-5> 5</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-6><a class=lnlinks href=#hl-19-6> 6</a></span><span class=cl><span class=w> </span><span class=nt>compositeTypeRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-7><a class=lnlinks href=#hl-19-7> 7</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>example.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-8><a class=lnlinks href=#hl-19-8> 8</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>XBucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-9><a class=lnlinks href=#hl-19-9> 9</a></span><span class=cl><span class=w> </span><span class=nt>mode</span><span class=p>:</span><span class=w> </span><span class=l>Pipeline</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-10><a class=lnlinks href=#hl-19-10>10</a></span><span class=cl><span class=w> </span><span class=nt>pipeline</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-11><a class=lnlinks href=#hl-19-11>11</a></span><span class=cl><span class=w> </span>- <span class=nt>step</span><span class=p>:</span><span class=w> </span><span class=l>patch-and-transform</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-12><a class=lnlinks href=#hl-19-12>12</a></span><span class=cl><span class=w> </span><span class=nt>functionRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-13><a class=lnlinks href=#hl-19-13>13</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>function-patch-and-transform</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-14><a class=lnlinks href=#hl-19-14>14</a></span><span class=cl><span class=w> </span><span class=nt>input</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-15><a class=lnlinks href=#hl-19-15>15</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>pt.fn.crossplane.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-16><a class=lnlinks href=#hl-19-16>16</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Resources</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-17><a class=lnlinks href=#hl-19-17>17</a></span><span class=cl><span class=w> </span><span class=nt>resources</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-18><a class=lnlinks href=#hl-19-18>18</a></span><span class=cl><span class=w> </span>- <span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>storage-bucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-19><a class=lnlinks href=#hl-19-19>19</a></span><span class=cl><span class=w> </span><span class=nt>base</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-20><a class=lnlinks href=#hl-19-20>20</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>s3.aws.upbound.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-21><a class=lnlinks href=#hl-19-21>21</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>Bucket</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-22><a class=lnlinks href=#hl-19-22>22</a></span><span class=cl><span class=w> </span><span class=nt>patches</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-23><a class=lnlinks href=#hl-19-23>23</a></span><span class=cl><span class=w> </span>- <span class=nt>type</span><span class=p>:</span><span class=w> </span><span class=l>FromCompositeFieldPath</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-24><a class=lnlinks href=#hl-19-24>24</a></span><span class=cl><span class=w> </span><span class=nt>fromFieldPath</span><span class=p>:</span><span class=w> </span><span class=l>spec.bucketRegion</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-19-25><a class=lnlinks href=#hl-19-25>25</a></span><span class=cl><span class=w> </span><span class=nt>toFieldPath</span><span class=p>:</span><span class=w> </span><span class=l>spec.forProvider.region</span><span class=w> </span></span></span></code></pre></div><div class="admonition important d-flex flex-column mx-4 p-0"><div class=admonition-title><svg class="bi flex-shrink-0" role="img" aria-label="important:"><use xlink:href="#exclamation"/></svg><span class=ps-1>Important</span></div><div class=admonition-content>Crossplane doesn&rsquo;t validate function input. It&rsquo;s a good idea for a function to validate its own input.</div></div><h3 id=function-pipeline-context>Function pipeline context <a class=anchor-link id=function-pipeline-context href=#function-pipeline-context aria-label="Link to this section: Function pipeline context"></a></h3><p>Sometimes two functions in a pipeline want to share information with each other that isn&rsquo;t desired state. Functions can use context for this. Any function can write to the pipeline context. Crossplane passes the context to all following functions. When Crossplane has called all functions it discards the pipeline context.</p><p>Crossplane can write context too. If you enable the alpha <a href=https://docs.crossplane.io/v1.18/concepts/environment-configs/>composition environment</a> feature Crossplane writes the environment to the top-level context field <code>apiextensions.crossplane.io/environment</code>.</p></div></main></div><script src=http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js type=text/javascript></script> <script type=module> import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs'; document.addEventListener("DOMContentLoaded", setMermaidStyle()); document.addEventListener("DOMContentLoaded", colorModeListener()); function getMermaidConfig(){ var style = getComputedStyle(document.body) var font = style.getPropertyValue("font-family") var fontColor = style.getPropertyValue('--body-font-color') var backgroundColor = style.getPropertyValue('--body-background') var config = { "theme": "base", "fontFamily": font, "themeVariables": { "background": backgroundColor, "textColor": fontColor, } } return config } function setMermaidStyle(){ var config = getMermaidConfig() mermaid.initialize( config ) } function colorModeListener(){ darkSwitch.addEventListener("click", resetMermaidStyle()) } function resetMermaidStyle(){ console.log("resetting") var config = getMermaidConfig() console.log(config) mermaid.mermaidAPI.setConfig( config ) mermaid.mermaidAPI.reset() } </script><footer class="bd-footer p-5"><div class="container text-center"><div class="row pb-5 top-row"><div class="col-lg img-col"><img src=/img/crossplane-logo.svg alt="Crossplane logo" srcset="/img/crossplane-logo.svg 1x, /img/crossplane-logo.svg 2x" width=185 height=40 decoding=async data-nimg=future loading=lazy class="d-flex crossplane-footer"></div><div class="col-lg links-col d-fill justify-content-evenly ms-5"><div class=row><div class=col-lg><a class=footer-link target=_blank href=https://twitter.com/crossplane_io>Twitter</a></div><div class=col-lg><a class=footer-link target=_blank href=https://www.youtube.com/channel/UC19FgzMBMqBro361HbE46Fw>Youtube</a></div><div class=col-lg><a class=footer-link target=_blank href="https://www.youtube.com/playlist?list=PL510POnNVaaYFuK-B_SIUrpIonCtLVOzT">Podcast</a></div><div class=col-lg><a class=footer-link target=_blank href=https://groups.google.com/g/crossplane-dev>Forum</a></div></div></div></div><div class="row pb-5"><div class="col-lg copyright-col pe-4 border-end"><p>© Crossplane Authors 2024. Documentation distributed under <a target=_blank href=https://creativecommons.org/licenses/by/4.0/>CC-BY-4.0</a>.</p><p>© 2024 The Linux Foundation. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our <a target=_blank href=https://www.linuxfoundation.org/legal/trademark-usage>Trademark Usage</a> page.</p></div><div class="col-lg cncf-col ms-5"><a class=d-flex target=_blank href=https://www.cncf.io/><img alt=cncfLogo src=/img/cncf-white.webp width=702 height=114 decoding=async data-nimg=future loading=lazy class="cncf-footer py-3"></a><p class=d-flex>We are a Cloud Native Computing Foundation incubating project.</p></div></div></div></footer><script src=https://docs.crossplane.io/js/main-727bf178.bundle.min.js data-no-instant></script><script type=text/javascript>(function(e,t,n,s,o,i,a){e[n]=e[n]||function(){(e[n].q=e[n].q||[]).push(arguments)},i=t.createElement(s),i.async=1,i.src="https://www.clarity.ms/tag/"+o,a=t.getElementsByTagName(s)[0],a.parentNode.insertBefore(i,a)})(window,document,"clarity","script","el5517lxor")</script> <script>(function(e,t,n,s,o){e[s]=e[s]||[],e[s].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var a=t.getElementsByTagName(n)[0],i=t.createElement(n),r=s!="dataLayer"?"&l="+s:"";i.async=!0,i.src="https://www.googletagmanager.com/gtm.js?id="+o+r,a.parentNode.insertBefore(i,a)})(window,document,"script","dataLayer","GTM-WFF2NQHG")</script><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-WFF2NQHG" height=0 width=0 style=display:none;visibility:hidden></iframe></noscript><script type=text/javascript>adroll_adv_id="B4XQTO44VJFVDGCGM332GU",adroll_pix_id="6ROIBHUPMVCSXN7HHIKJTK",adroll_version="2.0",function(e,t,n,s,o){e.__adroll_loaded=!0,e.adroll=e.adroll||[],e.adroll.f=["setProperties","identify","track"];var i="https://s.adroll.com/j/"+adroll_adv_id+"/roundtrip.js";for(o=0;o<e.adroll.f.length;o++)e.adroll[e.adroll.f[o]]=e.adroll[e.adroll.f[o]]||function(t){return function(){e.adroll.push([t,arguments])}}(e.adroll.f[o]);n=t.createElement("script"),s=t.getElementsByTagName("script")[0],n.async=1,n.src=i,s.parentNode.insertBefore(n,s)}(window,document),adroll.track("pageView")</script><script src=https://cdn.jsdelivr.net/npm/@docsearch/js@3></script> <script>docsearch({container:"#docSearch",appId:"9UXKYX61NK",indexName:"crossplane",apiKey:"e07e181044d561f6a4cb7261931d980a",placeholder:"Search the docs"})</script></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10